로컬 PC 이관 — git 제외 로컬 파일 보관 (manifest·.live 백업·tmp·이 PC 감사 로그) (PD 지시)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
@ -0,0 +1,45 @@
|
||||||
|
# `.live/` 실시간 공유 체계 — 실무 사용 안내
|
||||||
|
|
||||||
|
> **역할 분담**: 본 README는 **실무 사용 쿡북**이며, 규칙·헌법급 정의는 [`.claude/skills/너드나비스-코어룰/SKILL.md`](../../.claude/skills/너드나비스-코어룰/SKILL.md) **C34** 단일 SOT. 본 파일은 레포 `.live/` 경로에서 junction 경유로 접근하며, 중앙 저장소는 `$HOME/.claude/nerdnavis-live/`.
|
||||||
|
|
||||||
|
## 1. `.live/` 용도
|
||||||
|
|
||||||
|
세션 중 변경된 설정·규칙·에이전트 정의·조직 기억을 **세션 갱신 없이 즉시 반영**하기 위한 PC 로컬 실시간 공유 채널. 같은 PC 내 모든 세션(worktree 경계 무관)이 자동 주입받는다.
|
||||||
|
|
||||||
|
## 2. 더미 파일 패턴
|
||||||
|
|
||||||
|
- 파일명: `{변경 대상 파일명 또는 주제}.md`
|
||||||
|
- 예: `CLAUDE.md.live`·`C34_memory_확장.md`·`pd_지시_50.md`
|
||||||
|
- 본문: 변경 요지 append-only. 최대 8,000자
|
||||||
|
|
||||||
|
## 3. 생명주기
|
||||||
|
|
||||||
|
| 시점 | 상태 | 처리 |
|
||||||
|
|------|------|------|
|
||||||
|
| 변경 발생 | PM이 `.live/{파일명}` append | 원본 수정과 동시 수행 |
|
||||||
|
| 같은 PC 다른 세션 | UserPromptSubmit hook 자동 주입 | 증분만 읽기 (토큰 비용 최소) |
|
||||||
|
| "세션 공유"·push 시점 | P21-2 트리거 | 원본 반영 확인 후 `.live/` 비움(README.md·.junction-marker 제외) + commit + push |
|
||||||
|
|
||||||
|
## 4. 세션 간 공유 시나리오
|
||||||
|
|
||||||
|
### 같은 PC 내
|
||||||
|
1. 세션 A에서 원본 수정 + `.live/` append
|
||||||
|
2. 세션 B 다음 프롬프트 → UserPromptSubmit hook `live_inject.sh` 증분 주입
|
||||||
|
3. 즉시 인지 (git 개입 없음)
|
||||||
|
|
||||||
|
### 다른 PC 간
|
||||||
|
1. 세션 A "세션 공유" (P21-2) → `.live/` 비움 + commit + push
|
||||||
|
2. 세션 B (다른 PC) "세션 갱신" (P21) → git pull → SessionStart hook 자동 복원
|
||||||
|
|
||||||
|
## 5. 참조
|
||||||
|
|
||||||
|
- **SKILL.md C34** — PC 로컬 실시간 공유 중앙화 체계 (단일 SOT, 헌법급)
|
||||||
|
- **SKILL.md C21** — 작업 완료 즉시 공유·PM 능동 확인 (내부 공유/공유 완료 2단계)
|
||||||
|
- **scripts/live_junction_ensure.sh** — junction 자동 보장 (SessionStart + UserPromptSubmit hook)
|
||||||
|
- **scripts/live_inject.sh** — UserPromptSubmit hook 증분 주입
|
||||||
|
- **scripts/live_session_load.sh** — SessionStart 전량 1회 로드
|
||||||
|
|
||||||
|
## 변경 이력
|
||||||
|
|
||||||
|
- 2026-04-19: 전 세션 초기 sentinel 손실 시 원본 소실
|
||||||
|
- 2026-04-20: #48 D 집행으로 복구. 중앙 저장소에 신규 작성 (모든 PC 자동 동기화)
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
---
|
||||||
|
plan_id: 2026-05-28_기획팀장_남은업무보고
|
||||||
|
created_at: 2026-05-28T11:40:37+09:00
|
||||||
|
hostname: DESKTOP-RD7PUKN
|
||||||
|
goal: "PD 호칭 '기획팀장' 직접 지시 — 남은 기획 업무 현황 보고 (C43 정합)"
|
||||||
|
target_files:
|
||||||
|
- 공유/PD_지시_트래킹/기획팀_PD_지시_로그.md
|
||||||
|
- 공유/대화로그/EerieVillage/2026-05-28.md
|
||||||
|
- 공유/대화로그/조직운영/2026-05-28.md
|
||||||
|
completion_criteria: "commit + push 완료 후 post-commit hook archived 이동"
|
||||||
|
---
|
||||||
|
|
||||||
|
# 매니페스트 — 2026-05-28_기획팀장_남은업무보고
|
||||||
|
|
||||||
|
- **등록 시각**: 2026-05-28T11:40:38+09:00
|
||||||
|
- **호스트**: DESKTOP-RD7PUKN
|
||||||
|
- **집행 목표**: PD 호칭 '기획팀장' 직접 지시 — 남은 기획 업무 현황 보고 (C43 정합)
|
||||||
|
|
||||||
|
## 대상 파일
|
||||||
|
- `공유/PD_지시_트래킹/기획팀_PD_지시_로그.md`
|
||||||
|
- `공유/대화로그/EerieVillage/2026-05-28.md`
|
||||||
|
- `공유/대화로그/조직운영/2026-05-28.md`
|
||||||
|
|
||||||
|
## 완료 기준
|
||||||
|
|
||||||
|
commit + push 완료. post-commit hook이 `archived/2026-05-28_기획팀장_남은업무보고.md`로 자동 이동 + target_files cross-check.
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
2026-04-24_12:54:21 pm-auditor called
|
||||||
|
2026-04-24_14:42:16 pm-auditor called
|
||||||
|
2026-04-24_14:53:53 pm-auditor called
|
||||||
|
2026-04-24_14:59:36 pm-auditor called
|
||||||
|
2026-04-24_15:11:51 pm-auditor called
|
||||||
|
2026-04-24_15:20:06 pm-auditor called
|
||||||
|
2026-04-24_15:24:52 pm-auditor called
|
||||||
|
2026-04-24_16:12:14 pm-auditor called
|
||||||
|
2026-04-24_21:19:23 pm-auditor called
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
import os, sys
|
||||||
|
sys.stdout.reconfigure(encoding='utf-8')
|
||||||
|
from pptx import Presentation
|
||||||
|
from pptx.util import Emu
|
||||||
|
|
||||||
|
src = r'C:\Users\PC\Documents\카카오톡 받은 파일\[포트폴리오] 이승우_2019_2.12.22_(구버전).pptx'
|
||||||
|
prs = Presentation(src)
|
||||||
|
|
||||||
|
print(f'슬라이드 수: {len(prs.slides)}')
|
||||||
|
print(f'크기: {Emu(prs.slide_width).inches:.2f} x {Emu(prs.slide_height).inches:.2f} inches')
|
||||||
|
print(f'aspect: {prs.slide_width / prs.slide_height:.4f}')
|
||||||
|
print()
|
||||||
|
|
||||||
|
for i, slide in enumerate(prs.slides, 1):
|
||||||
|
print(f'=== Slide {i} (Layout: {slide.slide_layout.name}) ===')
|
||||||
|
img = 0
|
||||||
|
txt_lines = []
|
||||||
|
for shape in slide.shapes:
|
||||||
|
if shape.shape_type == 13:
|
||||||
|
img += 1
|
||||||
|
if shape.has_text_frame:
|
||||||
|
for para in shape.text_frame.paragraphs:
|
||||||
|
t = para.text.strip()
|
||||||
|
if t:
|
||||||
|
txt_lines.append(t)
|
||||||
|
print(f' images={img}, text_runs={len(txt_lines)}')
|
||||||
|
for j, line in enumerate(txt_lines[:30]):
|
||||||
|
print(f' T{j+1}: {line[:200]}')
|
||||||
|
print()
|
||||||
|
|
@ -0,0 +1,748 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
[포트폴리오] 이승우 — 16:9 와이드 현대화 PPT 빌드
|
||||||
|
- 4:3 (10x7.5) → 16:9 (13.33x7.5)
|
||||||
|
- Charcoal Minimal + Navy Accent 팔레트
|
||||||
|
- 게임 기획자 포트폴리오 톤 (전문성·정제)
|
||||||
|
"""
|
||||||
|
import os, sys
|
||||||
|
sys.stdout.reconfigure(encoding='utf-8')
|
||||||
|
|
||||||
|
from pptx import Presentation
|
||||||
|
from pptx.util import Inches, Pt, Emu
|
||||||
|
from pptx.enum.shapes import MSO_SHAPE
|
||||||
|
from pptx.dml.color import RGBColor
|
||||||
|
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
|
||||||
|
from pptx.oxml.ns import qn
|
||||||
|
from copy import deepcopy
|
||||||
|
from lxml import etree
|
||||||
|
|
||||||
|
# ─────────────── 디자인 시스템 ───────────────
|
||||||
|
COLOR_PRIMARY = RGBColor(0x1E, 0x27, 0x61) # navy (Midnight Executive)
|
||||||
|
COLOR_DARK = RGBColor(0x21, 0x29, 0x5C) # midnight
|
||||||
|
COLOR_BG_DARK = RGBColor(0x14, 0x1B, 0x42) # darker navy
|
||||||
|
COLOR_ACCENT = RGBColor(0xCA, 0xDC, 0xFC) # ice blue
|
||||||
|
COLOR_GOLD = RGBColor(0xC9, 0xA2, 0x4B) # gold accent (prestige)
|
||||||
|
COLOR_TEXT = RGBColor(0x21, 0x21, 0x21) # near black
|
||||||
|
COLOR_MUTED = RGBColor(0x6B, 0x72, 0x80) # gray
|
||||||
|
COLOR_LIGHT = RGBColor(0xF5, 0xF6, 0xFA) # light bg
|
||||||
|
COLOR_BORDER = RGBColor(0xE2, 0xE5, 0xEC) # border
|
||||||
|
COLOR_WHITE = RGBColor(0xFF, 0xFF, 0xFF)
|
||||||
|
|
||||||
|
FONT_HEADER = 'Malgun Gothic'
|
||||||
|
FONT_BODY = 'Malgun Gothic'
|
||||||
|
FONT_MONO = 'Consolas'
|
||||||
|
|
||||||
|
# 16:9 와이드 (PowerPoint 2019 표준)
|
||||||
|
SLIDE_W = Inches(13.333)
|
||||||
|
SLIDE_H = Inches(7.5)
|
||||||
|
|
||||||
|
OUT_PATH = r'C:\Users\PC\Documents\카카오톡 받은 파일\[포트폴리오] 이승우_2019_2.12.22_(현대화).pptx'
|
||||||
|
IMG_DIR = r'D:\NerdNavis\BurningTimesAi\tmp\portfolio_images'
|
||||||
|
|
||||||
|
|
||||||
|
def add_textbox(slide, left, top, width, height, text, *,
|
||||||
|
font=FONT_BODY, size=14, bold=False, italic=False,
|
||||||
|
color=COLOR_TEXT, align=PP_ALIGN.LEFT, anchor=MSO_ANCHOR.TOP,
|
||||||
|
line_spacing=1.15):
|
||||||
|
tb = slide.shapes.add_textbox(left, top, width, height)
|
||||||
|
tf = tb.text_frame
|
||||||
|
tf.margin_left = Inches(0.05)
|
||||||
|
tf.margin_right = Inches(0.05)
|
||||||
|
tf.margin_top = Inches(0.02)
|
||||||
|
tf.margin_bottom = Inches(0.02)
|
||||||
|
tf.word_wrap = True
|
||||||
|
tf.vertical_anchor = anchor
|
||||||
|
lines = text.split('\n') if isinstance(text, str) else text
|
||||||
|
for i, line in enumerate(lines):
|
||||||
|
p = tf.paragraphs[0] if i == 0 else tf.add_paragraph()
|
||||||
|
p.alignment = align
|
||||||
|
p.line_spacing = line_spacing
|
||||||
|
run = p.add_run()
|
||||||
|
run.text = line
|
||||||
|
run.font.name = font
|
||||||
|
run.font.size = Pt(size)
|
||||||
|
run.font.bold = bold
|
||||||
|
run.font.italic = italic
|
||||||
|
run.font.color.rgb = color
|
||||||
|
return tb
|
||||||
|
|
||||||
|
|
||||||
|
def add_rect(slide, left, top, width, height, fill_color, line_color=None, shadow=False):
|
||||||
|
shp = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, left, top, width, height)
|
||||||
|
shp.fill.solid()
|
||||||
|
shp.fill.fore_color.rgb = fill_color
|
||||||
|
if line_color is None:
|
||||||
|
shp.line.fill.background()
|
||||||
|
else:
|
||||||
|
shp.line.color.rgb = line_color
|
||||||
|
shp.line.width = Pt(0.5)
|
||||||
|
if not shadow:
|
||||||
|
# 그림자 제거
|
||||||
|
sp = shp.shadow
|
||||||
|
try:
|
||||||
|
sp.inherit = False
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return shp
|
||||||
|
|
||||||
|
|
||||||
|
def add_rounded(slide, left, top, width, height, fill_color, line_color=None):
|
||||||
|
shp = slide.shapes.add_shape(MSO_SHAPE.ROUNDED_RECTANGLE, left, top, width, height)
|
||||||
|
shp.adjustments[0] = 0.08
|
||||||
|
shp.fill.solid()
|
||||||
|
shp.fill.fore_color.rgb = fill_color
|
||||||
|
if line_color is None:
|
||||||
|
shp.line.fill.background()
|
||||||
|
else:
|
||||||
|
shp.line.color.rgb = line_color
|
||||||
|
shp.line.width = Pt(0.75)
|
||||||
|
return shp
|
||||||
|
|
||||||
|
|
||||||
|
def add_circle(slide, left, top, size, fill_color, line_color=None):
|
||||||
|
shp = slide.shapes.add_shape(MSO_SHAPE.OVAL, left, top, size, size)
|
||||||
|
shp.fill.solid()
|
||||||
|
shp.fill.fore_color.rgb = fill_color
|
||||||
|
if line_color is None:
|
||||||
|
shp.line.fill.background()
|
||||||
|
else:
|
||||||
|
shp.line.color.rgb = line_color
|
||||||
|
return shp
|
||||||
|
|
||||||
|
|
||||||
|
def page_header(slide, page_num, total=20, section=''):
|
||||||
|
"""우상단 페이지·섹션 표기 (간결)"""
|
||||||
|
add_textbox(slide, Inches(11.5), Inches(0.25), Inches(1.7), Inches(0.3),
|
||||||
|
f'{section} {page_num:02d} / {total:02d}',
|
||||||
|
size=9, color=COLOR_MUTED, align=PP_ALIGN.RIGHT)
|
||||||
|
|
||||||
|
|
||||||
|
def page_footer(slide):
|
||||||
|
"""좌하단 푸터 — 이름·연락"""
|
||||||
|
add_textbox(slide, Inches(0.5), Inches(7.05), Inches(8), Inches(0.3),
|
||||||
|
'Portfolio · 이승우 · Game Designer',
|
||||||
|
size=9, color=COLOR_MUTED, align=PP_ALIGN.LEFT)
|
||||||
|
|
||||||
|
|
||||||
|
# ─────────────── PPT 생성 시작 ───────────────
|
||||||
|
prs = Presentation()
|
||||||
|
prs.slide_width = SLIDE_W
|
||||||
|
prs.slide_height = SLIDE_H
|
||||||
|
blank_layout = prs.slide_layouts[6]
|
||||||
|
|
||||||
|
|
||||||
|
# ═══════════════ S1. 표지 ═══════════════
|
||||||
|
def build_slide_01():
|
||||||
|
s = prs.slides.add_slide(blank_layout)
|
||||||
|
# 풀블리드 다크 배경
|
||||||
|
add_rect(s, 0, 0, SLIDE_W, SLIDE_H, COLOR_BG_DARK)
|
||||||
|
# 좌측 navy 강조 띠 (단일 면 모티프)
|
||||||
|
add_rect(s, 0, 0, Inches(0.25), SLIDE_H, COLOR_GOLD)
|
||||||
|
|
||||||
|
# 제목군 (중앙 좌측 정렬)
|
||||||
|
add_textbox(s, Inches(1.0), Inches(2.4), Inches(8), Inches(0.5),
|
||||||
|
'PORTFOLIO',
|
||||||
|
size=14, bold=True, color=COLOR_GOLD,
|
||||||
|
font=FONT_HEADER, align=PP_ALIGN.LEFT)
|
||||||
|
add_textbox(s, Inches(1.0), Inches(2.9), Inches(11), Inches(1.3),
|
||||||
|
'포트폴리오',
|
||||||
|
size=72, bold=True, color=COLOR_WHITE,
|
||||||
|
font=FONT_HEADER, align=PP_ALIGN.LEFT)
|
||||||
|
add_textbox(s, Inches(1.0), Inches(4.4), Inches(11), Inches(0.6),
|
||||||
|
'RPG 개발 경험이 풍부한 제너럴리스트 게임 기획자',
|
||||||
|
size=22, color=COLOR_ACCENT,
|
||||||
|
font=FONT_HEADER, align=PP_ALIGN.LEFT)
|
||||||
|
|
||||||
|
# 구분선
|
||||||
|
add_rect(s, Inches(1.0), Inches(5.3), Inches(2.5), Inches(0.04), COLOR_GOLD)
|
||||||
|
|
||||||
|
# 이름·날짜
|
||||||
|
add_textbox(s, Inches(1.0), Inches(5.5), Inches(8), Inches(0.4),
|
||||||
|
'게임 기획자 · 이승우',
|
||||||
|
size=18, bold=True, color=COLOR_WHITE,
|
||||||
|
font=FONT_HEADER, align=PP_ALIGN.LEFT)
|
||||||
|
add_textbox(s, Inches(1.0), Inches(6.0), Inches(8), Inches(0.3),
|
||||||
|
'2019.12.22',
|
||||||
|
size=12, color=COLOR_ACCENT,
|
||||||
|
font=FONT_BODY, align=PP_ALIGN.LEFT)
|
||||||
|
|
||||||
|
|
||||||
|
# ═══════════════ S2. 대표 작품 인덱스 ═══════════════
|
||||||
|
def build_slide_02():
|
||||||
|
s = prs.slides.add_slide(blank_layout)
|
||||||
|
add_rect(s, 0, 0, SLIDE_W, SLIDE_H, COLOR_WHITE)
|
||||||
|
|
||||||
|
# 헤더
|
||||||
|
add_textbox(s, Inches(0.6), Inches(0.5), Inches(10), Inches(0.4),
|
||||||
|
'01 · Featured Works',
|
||||||
|
size=12, bold=True, color=COLOR_GOLD,
|
||||||
|
font=FONT_HEADER, align=PP_ALIGN.LEFT)
|
||||||
|
add_textbox(s, Inches(0.6), Inches(0.85), Inches(12), Inches(0.7),
|
||||||
|
'대표 작품 소개',
|
||||||
|
size=36, bold=True, color=COLOR_PRIMARY,
|
||||||
|
font=FONT_HEADER, align=PP_ALIGN.LEFT)
|
||||||
|
add_textbox(s, Inches(0.6), Inches(1.55), Inches(12), Inches(0.4),
|
||||||
|
'총 13개 작품 · 최근 런칭 시점 기준 정렬',
|
||||||
|
size=12, color=COLOR_MUTED,
|
||||||
|
font=FONT_BODY, align=PP_ALIGN.LEFT)
|
||||||
|
page_header(s, 2, section='WORKS INDEX')
|
||||||
|
|
||||||
|
works = [
|
||||||
|
('01', '매직 AR', '2019 · AR기반 실시간 전략 PvP'),
|
||||||
|
('02', '쿠로네코 (가제)', '캐릭터 수집 방치형 RPG · 개발 중단'),
|
||||||
|
('03', '만렙 영웅 키우기 시리즈', '2017 · 방치형 RPG · 매출 168위'),
|
||||||
|
('04', '프로젝트 BC', '하드코어 액션 MORPG · 80% 진행'),
|
||||||
|
('05', '데빌즈 아레나', '수집 성장형 MORPG · 개발 중단'),
|
||||||
|
('06', '드래곤 헌터스', '2015 · 액션 RPG · 인기 인디 선정'),
|
||||||
|
('07', '데빌즈', '2013 · 액션 RPG · 인기 무료 1위'),
|
||||||
|
('08', '동물 그림 맞추기', '2012 · 퍼즐 / 교육 어플'),
|
||||||
|
('09', '마스터 오브 던전', '2012 · 시나리오형 액션 RPG'),
|
||||||
|
('10', '최종병기 활', '2011 · 로그라이크 · 영화 OSMU'),
|
||||||
|
('11', '디스트로이어', '2010 · 액션 RPG · 넥슨 퍼블리싱'),
|
||||||
|
('12', '에프터 스쿨', '2009 · 미니게임 + 타이쿤'),
|
||||||
|
('13', '학교가는 길', '2007 · 미니게임 · SKT 킬러 콘텐츠'),
|
||||||
|
]
|
||||||
|
cols = 3
|
||||||
|
cell_w = Inches(4.0)
|
||||||
|
cell_h = Inches(0.85)
|
||||||
|
start_x = Inches(0.55)
|
||||||
|
start_y = Inches(2.2)
|
||||||
|
gap_x = Inches(0.1)
|
||||||
|
gap_y = Inches(0.12)
|
||||||
|
|
||||||
|
for i, (num, title, desc) in enumerate(works):
|
||||||
|
r, c = i // cols, i % cols
|
||||||
|
x = start_x + c * (cell_w + gap_x)
|
||||||
|
y = start_y + r * (cell_h + gap_y)
|
||||||
|
# 카드
|
||||||
|
card = add_rounded(s, x, y, cell_w, cell_h, COLOR_LIGHT, COLOR_BORDER)
|
||||||
|
# 좌측 번호 박스 (navy)
|
||||||
|
add_rect(s, x + Inches(0.0), y, Inches(0.6), cell_h, COLOR_PRIMARY)
|
||||||
|
add_textbox(s, x, y, Inches(0.6), cell_h,
|
||||||
|
num, size=18, bold=True, color=COLOR_WHITE,
|
||||||
|
font=FONT_HEADER, align=PP_ALIGN.CENTER, anchor=MSO_ANCHOR.MIDDLE)
|
||||||
|
# 제목
|
||||||
|
add_textbox(s, x + Inches(0.75), y + Inches(0.1), cell_w - Inches(0.85), Inches(0.35),
|
||||||
|
title, size=13, bold=True, color=COLOR_TEXT,
|
||||||
|
font=FONT_HEADER, align=PP_ALIGN.LEFT)
|
||||||
|
# 부제
|
||||||
|
add_textbox(s, x + Inches(0.75), y + Inches(0.42), cell_w - Inches(0.85), Inches(0.4),
|
||||||
|
desc, size=9.5, color=COLOR_MUTED,
|
||||||
|
font=FONT_BODY, align=PP_ALIGN.LEFT)
|
||||||
|
|
||||||
|
page_footer(s)
|
||||||
|
|
||||||
|
|
||||||
|
# ═══════════════ S3~S15. 게임 소개 슬라이드 (공통 레이아웃) ═══════════════
|
||||||
|
GAMES = [
|
||||||
|
# (페이지번호 in deck, 작품번호, title, subtitle, info_dict, overview_lines, role_text, kpi_text, image_filename)
|
||||||
|
(3, '01', '매직 AR', 'AR 기반의 전략 PvP 게임',
|
||||||
|
{'장르': 'AR기반 실시간 전략 PvP', '플랫폼': 'Android, iOS', '출시일': '2019. 09'},
|
||||||
|
[
|
||||||
|
'증강현실(AR)과 딥 러닝 기술을 활용해 음료수 캔 등 사물을 스캔하여 실제 게임에서 활용할 수 있는 새로운 개념의 게임.',
|
||||||
|
'클래시 로얄과 유사한 실시간 전략 PvP. 어떤 사물을 스캔하는지에 따라 다양한 변수가 발생되는 것이 특징.',
|
||||||
|
'신 기술 기반 투자 유치 목적의 프로젝트로, 게임성 개선 및 폴리싱 후 소프트 런칭 버전 대응 완료.',
|
||||||
|
'※ 개발부·사업부 간 게임에 대한 이해도 차이와 경영 사정 악화로 인해 퇴사 결정.',
|
||||||
|
],
|
||||||
|
'전투 밸런스 작업 · 게임 폴리싱 · 아이템 보상 시스템(상자·전투 보상) 등',
|
||||||
|
None,
|
||||||
|
'slide03_img10.jpg'),
|
||||||
|
(4, '02', '쿠로네코 (가제)', 'IP 활용 방치형 게임',
|
||||||
|
{'장르': '캐릭터 수집 방치형 RPG', '플랫폼': 'Android', '출시일': '개발 중단'},
|
||||||
|
[
|
||||||
|
'대만에서 흥행한 이노센트 IP를 활용한 캐릭터 수집·성장 방치형 RPG 프로젝트.',
|
||||||
|
'200여 종의 개성 있는 캐릭터 리소스를 활용해 수집·성장의 재미를 제공.',
|
||||||
|
'탱커/원딜/근딜러/서포터로 구성, 캐릭터마다 다양한 컨셉의 스킬로 전략적 덱 조합 가능.',
|
||||||
|
'원작 리소스를 활용해 개발기간을 단축, 캐릭터 가챠 BM으로 매출 극대화 구상.',
|
||||||
|
'※ 개발 진척 60% 달성 후 핵심 개발자 퇴사 및 내부 사정으로 개발 중단.',
|
||||||
|
],
|
||||||
|
'프로젝트 디렉팅(PD) · 핵심 시스템 기획 · UI&UX 컨셉팅 등 기획 실무 일체',
|
||||||
|
None,
|
||||||
|
'slide04_img13.png'),
|
||||||
|
(5, '03', '만렙 영웅 키우기 시리즈', '전사편 · 소환사편 · 마검사편',
|
||||||
|
{'장르': 'RPG / 방치형', '플랫폼': 'Android, iOS', '출시일': '2017. 04'},
|
||||||
|
[
|
||||||
|
'반복적인 자동 전투로 재화를 수집하고, 무한 환생을 통해 끊임없이 성장하는 방치형 RPG.',
|
||||||
|
'코어 RPG의 감성을 살린 아이템·스킬 시스템으로 기존 방치형 게임과의 차별화 어필.',
|
||||||
|
'총 개발기간 약 4개월. 전사편 지표 분석을 통해 의미 있는 성과 달성.',
|
||||||
|
'결투장·쟁탈전·랭킹 시스템 등 다양한 경쟁 컨텐츠로 유저 몰입 유도.',
|
||||||
|
],
|
||||||
|
'프로젝트 디렉팅(PD) · 기획 실무 일체',
|
||||||
|
'KPI: ARPPU ₩45,553 · Retention 36.7% (1Day) · 최고 매출 168위 · Featured 2017/05',
|
||||||
|
'slide05_img14.png'),
|
||||||
|
(6, '04', '프로젝트 BC', '푸른 별의 노래 (가제)',
|
||||||
|
{'장르': '하드코어 액션 MORPG', '플랫폼': 'Android', '출시일': '개발 중단'},
|
||||||
|
[
|
||||||
|
'화려한 2D 그래픽과 액션 RPG의 진수를 느낄 수 있는 하드코어 감성의 2D MORPG.',
|
||||||
|
'전사·마검사·소환사 3명의 캐릭터가 멀티 시나리오로 제공되며 각기 다른 플레이 스타일 보유.',
|
||||||
|
'유저간 PvP, RvR 형태의 길드 대전 및 약탈 시스템으로 경쟁 유도.',
|
||||||
|
'코스튬·펫·용병 시스템을 통해 캐릭터 성장 외에도 풍부한 즐길거리 제공.',
|
||||||
|
'※ 핵심 시스템 및 컨텐츠 80% 완성, 경영 악화로 인해 일시 중단.',
|
||||||
|
],
|
||||||
|
'핵심 시스템 및 컨텐츠 기획 · 몬스터 & 캐릭터 전투 시스템 관련 기획',
|
||||||
|
None,
|
||||||
|
None),
|
||||||
|
(7, '05', '데빌즈 아레나', '자사 IP 활용 액션 MORPG',
|
||||||
|
{'장르': '수집 성장형 MORPG', '플랫폼': 'Android', '출시일': '개발 중단'},
|
||||||
|
[
|
||||||
|
'데빌즈·마스터오브 던전 인기 캐릭터 + 오리지널 30여 종을 활용한 캐릭터 수집·성장 MORPG.',
|
||||||
|
'실시간 PvP를 비롯한 다양한 경쟁형 컨텐츠 제공.',
|
||||||
|
'캐릭터간 상성과 플레이 스타일이 다양해 수집·조작의 재미를 모두 추구.',
|
||||||
|
'※ 정부 지원사업과 연계해 70% 개발 진행, 개발기간 대비 수익성 부족으로 잠정 드랍.',
|
||||||
|
],
|
||||||
|
'프로젝트 디렉팅(PD) · 기획 실무 일체',
|
||||||
|
None,
|
||||||
|
None),
|
||||||
|
(8, '06', '드래곤 헌터스', '캐주얼 액션 RPG',
|
||||||
|
{'장르': '액션 RPG', '플랫폼': 'N스토어 / 원스토어 / GP2X', '출시일': '2015. 02'},
|
||||||
|
[
|
||||||
|
'피쳐폰 시절 이통 3사 25만 다운로드 이상을 기록하며 재미 검증을 받은 캐주얼 ARPG.',
|
||||||
|
'다이나믹한 콤보 액션과 필드 기믹으로 조작감에 대한 호평을 받음.',
|
||||||
|
'아이템 파밍·스킬 트리 구성으로 캐릭터 성장의 묘미 제공.',
|
||||||
|
'스마트폰 버전 리뉴얼 출시, 무리한 BM 적용으로 성과는 저조.',
|
||||||
|
],
|
||||||
|
'프로젝트 디렉팅(PD) · 기획 실무 일체',
|
||||||
|
'Featured: 인기 인디 게임 선정 (15/03)',
|
||||||
|
None),
|
||||||
|
(9, '07', '데빌즈', '몰입형 싱글 액션 RPG',
|
||||||
|
{'장르': '액션 RPG', '플랫폼': 'Android, iOS · 컴투스 퍼블리싱', '출시일': '2013. 10'},
|
||||||
|
[
|
||||||
|
'아이템 옵션 조합 파밍의 재미와 시나리오 기반 싱글 액션 RPG.',
|
||||||
|
'4명의 캐릭터가 각자 시점으로 진행되는 멀티 시나리오로 정통 RPG의 색다른 경험 제공.',
|
||||||
|
'다양한 옵션·등급 아이템과 스텟 포인트 투자로 성장 방법 다양화.',
|
||||||
|
'노말/하드/헬 난이도 + 최대 레벨 999로 장기 콘텐츠 제공, 보스 레이드·무한의 던전 등 다양한 싱글 컨텐츠 운영.',
|
||||||
|
'아이템 위주 BM을 통해 수년간 안정적 수익 창출.',
|
||||||
|
],
|
||||||
|
'핵심 시스템·컨텐츠 기획 · 기획 실무 일체 (맵 & 레벨 디자인 제외)',
|
||||||
|
'Featured: 인기 무료 게임 1위 (2013/11)',
|
||||||
|
None),
|
||||||
|
(10, '08', '동물 그림 맞추기', '유아 교육용 어플리케이션',
|
||||||
|
{'장르': '퍼즐 / 교육', '플랫폼': 'Android', '출시일': '2012. 09'},
|
||||||
|
[
|
||||||
|
'캐시카우 확보 및 기획팀 유니티 엔진 학습을 위한 단기 개발 프로젝트.',
|
||||||
|
'귀엽고 깔끔한 그래픽과 직관적인 게임 방법, 유아 교육용 어플리케이션으로 출시.',
|
||||||
|
'자사 게임 라인업 다양화 및 지속적 수익 타이틀 실험의 대표 케이스.',
|
||||||
|
'※ 총 인원 3명, 개발 기간 약 2.5주의 초단기 프로젝트.',
|
||||||
|
],
|
||||||
|
'아트 컨셉 · UI&UX 설계 · UI 프리펩 배치 등 실무',
|
||||||
|
None,
|
||||||
|
None),
|
||||||
|
(11, '09', '마스터 오브 던전', '시나리오형 액션 RPG',
|
||||||
|
{'장르': '액션 RPG', '플랫폼': 'Android', '출시일': '2012. 07'},
|
||||||
|
[
|
||||||
|
'디스트로이어의 개발 노하우와 엔진을 활용해 제작된 싱글 기반 시나리오형 액션 RPG.',
|
||||||
|
'짜임새 있는 시나리오와 퀘스트 이벤트로 엔딩까지의 과정을 풍성하게 구성.',
|
||||||
|
'캐릭터 육성 방식에 따라 특성이 부여되는 정통 RPG 표방.',
|
||||||
|
'몰이사냥과 다양한 옵션 아이템으로 장비 세팅·파밍의 재미 강조.',
|
||||||
|
'인앱 과금 시장으로의 전환기에서 다양한 BM 실험을 시도한 프로젝트.',
|
||||||
|
],
|
||||||
|
'아이템 및 전투 시스템 기획 · 시나리오 스크립트 작업 일체',
|
||||||
|
None,
|
||||||
|
'slide11_img11.jpg'),
|
||||||
|
(12, '10', '최종병기 활', '영화 OSMU 로그라이크',
|
||||||
|
{'장르': '로그라이크', '플랫폼': 'Android', '출시일': '2011. 09'},
|
||||||
|
[
|
||||||
|
'영화 「최종병기 활」 홍보를 위한 원소스 멀티유즈 전략 프로젝트.',
|
||||||
|
'영화 개봉 시점에 맞춰 출시하기 위해 로그라이크를 변형한 캐주얼 RPG로 기획.',
|
||||||
|
'영화 시나리오 플롯을 계승하되 게임만의 오리지날 요소를 가미해 색다른 재미 제공.',
|
||||||
|
'재화 수집 → 무기·방어구 성장 구조, 타이밍 조작감 강조.',
|
||||||
|
'※ 촉박한 일정과 단말기 커버리지 한계로 흥행에는 실패.',
|
||||||
|
],
|
||||||
|
'핵심 시스템 및 컨텐츠 기획 · 시나리오 스크립트 작업 등 기획 실무 일체',
|
||||||
|
None,
|
||||||
|
'slide12_img10.png'),
|
||||||
|
(13, '11', '디스트로이어', '대작 액션 RPG',
|
||||||
|
{'장르': '액션 RPG', '플랫폼': 'SKT / Android · 넥슨 모바일 퍼블리싱', '출시일': '2010. 09'},
|
||||||
|
[
|
||||||
|
'드래곤 헌터의 성공과 개발력을 검증받아 넥슨과 퍼블리싱 계약이 체결된 대작 액션 프로젝트.',
|
||||||
|
'당시 모바일 최초로 4명의 캐릭터가 각각의 시점으로 진행되는 멀티 시나리오 제공.',
|
||||||
|
'거대 보스 레이드, 실시간 PvP 등 방대한 컨텐츠와 풍부한 즐길거리로 플레이타임 확보.',
|
||||||
|
'영웅 서기를 능가하는 대작 RPG를 목표로 했으나, 개발기간 오버 및 피쳐폰→스마트폰 시장 급변기 직격.',
|
||||||
|
'터치 조작 미지원으로 흥행에는 실패한 비운의 프로젝트.',
|
||||||
|
],
|
||||||
|
'핵심 시스템 및 컨텐츠 기획 · 시나리오 스크립트 작업 등 기획 실무 일체',
|
||||||
|
None,
|
||||||
|
None),
|
||||||
|
(14, '12', '에프터 스쿨', '미니게임 + 타이쿤 복합',
|
||||||
|
{'장르': '미니게임', '플랫폼': 'SKT', '출시일': '2009. 06'},
|
||||||
|
[
|
||||||
|
'학교가는길 시리즈의 성공에 힘입어 독특하고 기발한 컨셉으로 제안·개발한 프로젝트.',
|
||||||
|
'미니게임과 타이쿤 장르를 믹스해 엄마 파트·아들 파트를 나눠 다양한 할 거리 제공.',
|
||||||
|
'초기 60~70% 개발 단계에서 ARPG(드래곤헌터) 메인 기획 담당을 위해 인수인계.',
|
||||||
|
'※ 신입 인력 인수 이후 타이쿤 장르 소화 부족으로 미니게임 장르 전환, 게임성 모호로 흥행 실패.',
|
||||||
|
],
|
||||||
|
'컨셉 기획 · 타이쿤 & 미니게임 초기 기획 담당',
|
||||||
|
None,
|
||||||
|
None),
|
||||||
|
(15, '13', '학교가는 길', 'SKT 킬러 콘텐츠',
|
||||||
|
{'장르': '미니게임', '플랫폼': 'Android', '출시일': '2007. 05'},
|
||||||
|
[
|
||||||
|
'SKT 킬러 컨텐츠로 선정되며 흥행에 성공한 최초의 프로젝트. 시리즈화에 성공해 3편까지 출시.',
|
||||||
|
'학교가는 길을 미니게임화한 독특한 컨셉과 개성 있는 디자인 연출로 피쳐폰 시절 높은 다운로드 수익 창출.',
|
||||||
|
'10여 종의 미니게임으로 구성. 각 미니게임은 외주 개발업체를 통해 진행.',
|
||||||
|
'초기 개발 단계부터 참여해 미니게임 전체 세부 기획·밸런싱·아트 컨셉 담당.',
|
||||||
|
'※ 퍼블리셔와의 수익 배분·라이선스 지분 이슈로 후속작은 타 업체 진행.',
|
||||||
|
],
|
||||||
|
'컨셉 기획 · 미니게임 8종 시스템 기획 · 외주 개발 업체 관리 등 실무 전반',
|
||||||
|
None,
|
||||||
|
None),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def build_game_slide(page, num, title, subtitle, info, overviews, role, kpi, img_file):
|
||||||
|
s = prs.slides.add_slide(blank_layout)
|
||||||
|
add_rect(s, 0, 0, SLIDE_W, SLIDE_H, COLOR_WHITE)
|
||||||
|
|
||||||
|
# 좌측 다크 사이드바 (게임 정보 카드)
|
||||||
|
SIDEBAR_W = Inches(4.2)
|
||||||
|
add_rect(s, 0, 0, SIDEBAR_W, SLIDE_H, COLOR_BG_DARK)
|
||||||
|
# 좌측 navy 강조 띠
|
||||||
|
add_rect(s, 0, 0, Inches(0.18), SLIDE_H, COLOR_GOLD)
|
||||||
|
|
||||||
|
# 사이드바 — 작품 번호
|
||||||
|
add_textbox(s, Inches(0.5), Inches(0.5), Inches(3.5), Inches(0.4),
|
||||||
|
f'WORK · {num}',
|
||||||
|
size=11, bold=True, color=COLOR_GOLD,
|
||||||
|
font=FONT_HEADER, align=PP_ALIGN.LEFT)
|
||||||
|
|
||||||
|
# 사이드바 — 게임명
|
||||||
|
add_textbox(s, Inches(0.5), Inches(0.95), Inches(3.5), Inches(1.0),
|
||||||
|
title, size=26, bold=True, color=COLOR_WHITE,
|
||||||
|
font=FONT_HEADER, align=PP_ALIGN.LEFT, line_spacing=1.1)
|
||||||
|
add_textbox(s, Inches(0.5), Inches(2.0), Inches(3.5), Inches(0.7),
|
||||||
|
subtitle, size=12, color=COLOR_ACCENT,
|
||||||
|
font=FONT_BODY, align=PP_ALIGN.LEFT, italic=True, line_spacing=1.3)
|
||||||
|
|
||||||
|
# 구분선
|
||||||
|
add_rect(s, Inches(0.5), Inches(2.95), Inches(0.6), Inches(0.025), COLOR_GOLD)
|
||||||
|
|
||||||
|
# 사이드바 — 게임 정보 표
|
||||||
|
y = Inches(3.15)
|
||||||
|
for label, value in info.items():
|
||||||
|
add_textbox(s, Inches(0.5), y, Inches(3.5), Inches(0.25),
|
||||||
|
label.upper(),
|
||||||
|
size=9, bold=True, color=COLOR_GOLD,
|
||||||
|
font=FONT_HEADER, align=PP_ALIGN.LEFT)
|
||||||
|
add_textbox(s, Inches(0.5), y + Inches(0.25), Inches(3.5), Inches(0.35),
|
||||||
|
value,
|
||||||
|
size=12, color=COLOR_WHITE,
|
||||||
|
font=FONT_BODY, align=PP_ALIGN.LEFT)
|
||||||
|
y += Inches(0.72)
|
||||||
|
|
||||||
|
# 사이드바 — 이미지 (있다면 하단)
|
||||||
|
if img_file:
|
||||||
|
img_path = os.path.join(IMG_DIR, img_file)
|
||||||
|
if os.path.exists(img_path):
|
||||||
|
try:
|
||||||
|
# 이미지 사이즈 측정 후 비율 유지
|
||||||
|
from PIL import Image
|
||||||
|
with Image.open(img_path) as pim:
|
||||||
|
iw, ih = pim.size
|
||||||
|
# 너비 3.3", 위치 사이드바 하단
|
||||||
|
max_w_in = 3.3
|
||||||
|
max_h_in = 1.4
|
||||||
|
ratio_img = iw / ih
|
||||||
|
ratio_box = max_w_in / max_h_in
|
||||||
|
if ratio_img >= ratio_box:
|
||||||
|
target_w = max_w_in
|
||||||
|
target_h = max_w_in / ratio_img
|
||||||
|
else:
|
||||||
|
target_h = max_h_in
|
||||||
|
target_w = max_h_in * ratio_img
|
||||||
|
ix = Inches((4.2 - target_w) / 2)
|
||||||
|
iy = Inches(5.95 - target_h / 2)
|
||||||
|
s.shapes.add_picture(img_path, ix, iy, Inches(target_w), Inches(target_h))
|
||||||
|
except Exception as e:
|
||||||
|
print(f' image warn: {e}')
|
||||||
|
|
||||||
|
# 우측 컨텐츠 영역
|
||||||
|
CONTENT_X = Inches(4.7)
|
||||||
|
# 상단 페이지 표기
|
||||||
|
add_textbox(s, Inches(11.5), Inches(0.5), Inches(1.7), Inches(0.3),
|
||||||
|
f'WORKS · {page:02d} / 20',
|
||||||
|
size=9, color=COLOR_MUTED, align=PP_ALIGN.RIGHT,
|
||||||
|
font=FONT_BODY)
|
||||||
|
|
||||||
|
# 우측 — 섹션 라벨
|
||||||
|
add_textbox(s, CONTENT_X, Inches(0.55), Inches(8), Inches(0.4),
|
||||||
|
'GAME OVERVIEW',
|
||||||
|
size=11, bold=True, color=COLOR_PRIMARY,
|
||||||
|
font=FONT_HEADER, align=PP_ALIGN.LEFT)
|
||||||
|
add_rect(s, CONTENT_X, Inches(0.95), Inches(0.6), Inches(0.04), COLOR_PRIMARY)
|
||||||
|
|
||||||
|
# 우측 — 게임 개요 (불릿형 단락)
|
||||||
|
y = Inches(1.15)
|
||||||
|
for line in overviews:
|
||||||
|
# 불릿 마커
|
||||||
|
dot = add_circle(s, CONTENT_X, y + Inches(0.12), Inches(0.08), COLOR_GOLD)
|
||||||
|
add_textbox(s, CONTENT_X + Inches(0.2), y, Inches(8.3), Inches(0.6),
|
||||||
|
line, size=11.5, color=COLOR_TEXT,
|
||||||
|
font=FONT_BODY, align=PP_ALIGN.LEFT, line_spacing=1.3)
|
||||||
|
# 라인 수에 따른 동적 간격
|
||||||
|
est_lines = max(1, (len(line) // 50) + 1)
|
||||||
|
y += Inches(0.34 + 0.22 * (est_lines - 1))
|
||||||
|
if y > Inches(5.3):
|
||||||
|
break
|
||||||
|
|
||||||
|
# 우측 — 담당 업무 박스
|
||||||
|
role_y = Inches(5.6)
|
||||||
|
add_rect(s, CONTENT_X, role_y, Inches(8.4), Inches(0.85), COLOR_LIGHT)
|
||||||
|
add_rect(s, CONTENT_X, role_y, Inches(0.1), Inches(0.85), COLOR_PRIMARY)
|
||||||
|
add_textbox(s, CONTENT_X + Inches(0.25), role_y + Inches(0.08), Inches(8), Inches(0.3),
|
||||||
|
'MY ROLE',
|
||||||
|
size=10, bold=True, color=COLOR_PRIMARY,
|
||||||
|
font=FONT_HEADER, align=PP_ALIGN.LEFT)
|
||||||
|
add_textbox(s, CONTENT_X + Inches(0.25), role_y + Inches(0.36), Inches(8), Inches(0.5),
|
||||||
|
role, size=11, color=COLOR_TEXT,
|
||||||
|
font=FONT_BODY, align=PP_ALIGN.LEFT)
|
||||||
|
|
||||||
|
# KPI / Featured 박스 (있을 경우)
|
||||||
|
if kpi:
|
||||||
|
kpi_y = Inches(6.6)
|
||||||
|
add_rect(s, CONTENT_X, kpi_y, Inches(8.4), Inches(0.6), COLOR_PRIMARY)
|
||||||
|
add_textbox(s, CONTENT_X + Inches(0.25), kpi_y + Inches(0.1), Inches(8), Inches(0.4),
|
||||||
|
'KPI / FEATURED',
|
||||||
|
size=9, bold=True, color=COLOR_GOLD,
|
||||||
|
font=FONT_HEADER, align=PP_ALIGN.LEFT)
|
||||||
|
add_textbox(s, CONTENT_X + Inches(0.25), kpi_y + Inches(0.3), Inches(8), Inches(0.4),
|
||||||
|
kpi, size=10.5, color=COLOR_WHITE,
|
||||||
|
font=FONT_BODY, align=PP_ALIGN.LEFT)
|
||||||
|
|
||||||
|
# 푸터
|
||||||
|
add_textbox(s, Inches(4.7), Inches(7.15), Inches(8), Inches(0.25),
|
||||||
|
'이승우 · Game Designer · Portfolio',
|
||||||
|
size=8, color=COLOR_MUTED, align=PP_ALIGN.LEFT,
|
||||||
|
font=FONT_BODY)
|
||||||
|
|
||||||
|
|
||||||
|
# ═══════════════ S16. 경력 개요 ═══════════════
|
||||||
|
def build_slide_16():
|
||||||
|
s = prs.slides.add_slide(blank_layout)
|
||||||
|
add_rect(s, 0, 0, SLIDE_W, SLIDE_H, COLOR_WHITE)
|
||||||
|
|
||||||
|
add_textbox(s, Inches(0.6), Inches(0.5), Inches(10), Inches(0.4),
|
||||||
|
'02 · Career Summary',
|
||||||
|
size=12, bold=True, color=COLOR_GOLD,
|
||||||
|
font=FONT_HEADER, align=PP_ALIGN.LEFT)
|
||||||
|
add_textbox(s, Inches(0.6), Inches(0.85), Inches(12), Inches(0.7),
|
||||||
|
'경력 개요',
|
||||||
|
size=36, bold=True, color=COLOR_PRIMARY,
|
||||||
|
font=FONT_HEADER, align=PP_ALIGN.LEFT)
|
||||||
|
add_textbox(s, Inches(0.6), Inches(1.55), Inches(12), Inches(0.4),
|
||||||
|
'총 경력 13년 2개월 · 다수의 메인 기획 및 디렉터 경험',
|
||||||
|
size=12, color=COLOR_MUTED,
|
||||||
|
font=FONT_BODY, align=PP_ALIGN.LEFT)
|
||||||
|
page_header(s, 16, section='CAREER')
|
||||||
|
|
||||||
|
# 큰 KPI 박스
|
||||||
|
add_rect(s, Inches(0.6), Inches(2.25), Inches(3.9), Inches(1.4), COLOR_BG_DARK)
|
||||||
|
add_rect(s, Inches(0.6), Inches(2.25), Inches(0.15), Inches(1.4), COLOR_GOLD)
|
||||||
|
add_textbox(s, Inches(0.85), Inches(2.4), Inches(3.5), Inches(0.4),
|
||||||
|
'TOTAL EXPERIENCE',
|
||||||
|
size=11, bold=True, color=COLOR_GOLD,
|
||||||
|
font=FONT_HEADER, align=PP_ALIGN.LEFT)
|
||||||
|
add_textbox(s, Inches(0.85), Inches(2.75), Inches(3.5), Inches(0.9),
|
||||||
|
'13년 2개월',
|
||||||
|
size=42, bold=True, color=COLOR_WHITE,
|
||||||
|
font=FONT_HEADER, align=PP_ALIGN.LEFT)
|
||||||
|
add_textbox(s, Inches(0.85), Inches(3.32), Inches(3.5), Inches(0.3),
|
||||||
|
'Game Designer · PD · PM',
|
||||||
|
size=11, color=COLOR_ACCENT,
|
||||||
|
font=FONT_BODY, italic=True, align=PP_ALIGN.LEFT)
|
||||||
|
|
||||||
|
# 우측 — 핵심 강점 그리드 (2 columns × 5 rows)
|
||||||
|
strengths = [
|
||||||
|
('PROJECT LEADING', '다수의 프로젝트에서 메인 기획 및 디렉터로 리딩 경험'),
|
||||||
|
('PROVEN HITS', '만렙 영웅 키우기, 데빌즈, 마스터 오브 던전, 드래곤 헌터, 학교가는 길'),
|
||||||
|
('GLOBAL SERVICE', '미국·중국·일본 등 글로벌 서비스 대응 경험 (데빌즈 외)'),
|
||||||
|
('MULTI-PLATFORM', 'NDS · GP2X · AR · 콘솔 / 모바일 등 다양한 플랫폼 실무'),
|
||||||
|
('LIVE OPERATIONS', '라이브 게임 운영 및 서비스 다수 보유'),
|
||||||
|
('PROACTIVE', '주도적인 프로젝트 제안·추진 (방치형·IP 활용 등)'),
|
||||||
|
('MULTI-ROLE', 'PD · PM · QA · 외주 개발 관리 등 다양한 포지션 이해'),
|
||||||
|
('NARRATIVE', '게임 시나리오 작성 및 스크립트 작업 (멀티 시나리오 포함)'),
|
||||||
|
('TOOLS', '스파인 · 협업 툴 · 발사믹 목업 · 마인드맵 등 효율적 활용'),
|
||||||
|
('BM DESIGN', '게임 통찰력·서비스 경험 기반 핵심 BM 설계 및 리뉴얼 주도'),
|
||||||
|
]
|
||||||
|
col_x = [Inches(4.85), Inches(9.05)]
|
||||||
|
cell_w = Inches(4.05)
|
||||||
|
cell_h = Inches(0.85)
|
||||||
|
start_y = Inches(2.25)
|
||||||
|
for i, (label, desc) in enumerate(strengths):
|
||||||
|
col = i % 2
|
||||||
|
row = i // 2
|
||||||
|
x = col_x[col]
|
||||||
|
y = start_y + row * (cell_h + Inches(0.1))
|
||||||
|
# 카드
|
||||||
|
card = add_rounded(s, x, y, cell_w, cell_h, COLOR_LIGHT, COLOR_BORDER)
|
||||||
|
# 좌측 아이콘 원 (gold) + 번호
|
||||||
|
add_circle(s, x + Inches(0.15), y + Inches(0.2), Inches(0.45), COLOR_PRIMARY)
|
||||||
|
add_textbox(s, x + Inches(0.15), y + Inches(0.2), Inches(0.45), Inches(0.45),
|
||||||
|
f'{i+1:02d}', size=10, bold=True, color=COLOR_GOLD,
|
||||||
|
font=FONT_HEADER, align=PP_ALIGN.CENTER, anchor=MSO_ANCHOR.MIDDLE)
|
||||||
|
# 라벨
|
||||||
|
add_textbox(s, x + Inches(0.7), y + Inches(0.12), cell_w - Inches(0.8), Inches(0.3),
|
||||||
|
label, size=10, bold=True, color=COLOR_PRIMARY,
|
||||||
|
font=FONT_HEADER, align=PP_ALIGN.LEFT)
|
||||||
|
# 본문
|
||||||
|
add_textbox(s, x + Inches(0.7), y + Inches(0.4), cell_w - Inches(0.8), Inches(0.45),
|
||||||
|
desc, size=10, color=COLOR_TEXT,
|
||||||
|
font=FONT_BODY, align=PP_ALIGN.LEFT, line_spacing=1.2)
|
||||||
|
|
||||||
|
# 하단 — 마지막 1 항목 (소규모 ~ 중형 조직 경험)
|
||||||
|
bottom_y = Inches(7.0)
|
||||||
|
add_textbox(s, Inches(0.6), bottom_y, Inches(12.2), Inches(0.3),
|
||||||
|
'★ 소규모 스타트업부터 중형급 이상의 개발 조직까지 다양한 실무 경험 보유',
|
||||||
|
size=11, bold=True, color=COLOR_PRIMARY,
|
||||||
|
font=FONT_HEADER, align=PP_ALIGN.LEFT)
|
||||||
|
|
||||||
|
page_footer(s)
|
||||||
|
|
||||||
|
|
||||||
|
# ═══════════════ S17·18·19. 영상 URL ═══════════════
|
||||||
|
def build_video_links_slide(page_num, section_title, items):
|
||||||
|
"""items: [(title, url, desc), ...]"""
|
||||||
|
s = prs.slides.add_slide(blank_layout)
|
||||||
|
add_rect(s, 0, 0, SLIDE_W, SLIDE_H, COLOR_WHITE)
|
||||||
|
add_textbox(s, Inches(0.6), Inches(0.5), Inches(10), Inches(0.4),
|
||||||
|
'03 · Reference Videos',
|
||||||
|
size=12, bold=True, color=COLOR_GOLD,
|
||||||
|
font=FONT_HEADER, align=PP_ALIGN.LEFT)
|
||||||
|
add_textbox(s, Inches(0.6), Inches(0.85), Inches(12), Inches(0.7),
|
||||||
|
section_title,
|
||||||
|
size=36, bold=True, color=COLOR_PRIMARY,
|
||||||
|
font=FONT_HEADER, align=PP_ALIGN.LEFT)
|
||||||
|
add_textbox(s, Inches(0.6), Inches(1.55), Inches(12), Inches(0.4),
|
||||||
|
'포트폴리오 참고 영상 / 다운로드 URL',
|
||||||
|
size=12, color=COLOR_MUTED,
|
||||||
|
font=FONT_BODY, align=PP_ALIGN.LEFT)
|
||||||
|
page_header(s, page_num, section='VIDEOS')
|
||||||
|
|
||||||
|
y = Inches(2.3)
|
||||||
|
for title, url, desc in items:
|
||||||
|
# 카드
|
||||||
|
add_rounded(s, Inches(0.6), y, Inches(12.15), Inches(1.3), COLOR_LIGHT, COLOR_BORDER)
|
||||||
|
# 좌측 navy 띠
|
||||||
|
add_rect(s, Inches(0.6), y, Inches(0.15), Inches(1.3), COLOR_PRIMARY)
|
||||||
|
# 제목
|
||||||
|
add_textbox(s, Inches(0.9), y + Inches(0.15), Inches(11.5), Inches(0.4),
|
||||||
|
title, size=15, bold=True, color=COLOR_PRIMARY,
|
||||||
|
font=FONT_HEADER, align=PP_ALIGN.LEFT)
|
||||||
|
# URL
|
||||||
|
add_textbox(s, Inches(0.9), y + Inches(0.55), Inches(11.5), Inches(0.35),
|
||||||
|
url, size=10.5, color=COLOR_GOLD,
|
||||||
|
font=FONT_MONO, align=PP_ALIGN.LEFT)
|
||||||
|
# 설명
|
||||||
|
if desc:
|
||||||
|
add_textbox(s, Inches(0.9), y + Inches(0.92), Inches(11.5), Inches(0.35),
|
||||||
|
desc, size=10, color=COLOR_MUTED,
|
||||||
|
font=FONT_BODY, italic=True, align=PP_ALIGN.LEFT)
|
||||||
|
y += Inches(1.5)
|
||||||
|
if y > Inches(6.5):
|
||||||
|
break
|
||||||
|
|
||||||
|
page_footer(s)
|
||||||
|
|
||||||
|
|
||||||
|
# ═══════════════ S20. 마무리·다운로드 ═══════════════
|
||||||
|
def build_slide_20():
|
||||||
|
s = prs.slides.add_slide(blank_layout)
|
||||||
|
add_rect(s, 0, 0, SLIDE_W, SLIDE_H, COLOR_BG_DARK)
|
||||||
|
# 좌측 띠
|
||||||
|
add_rect(s, 0, 0, Inches(0.25), SLIDE_H, COLOR_GOLD)
|
||||||
|
|
||||||
|
add_textbox(s, Inches(1.0), Inches(1.2), Inches(10), Inches(0.5),
|
||||||
|
'04 · Work Outputs',
|
||||||
|
size=14, bold=True, color=COLOR_GOLD,
|
||||||
|
font=FONT_HEADER, align=PP_ALIGN.LEFT)
|
||||||
|
add_textbox(s, Inches(1.0), Inches(1.7), Inches(11), Inches(1.0),
|
||||||
|
'실무 작업 결과물',
|
||||||
|
size=48, bold=True, color=COLOR_WHITE,
|
||||||
|
font=FONT_HEADER, align=PP_ALIGN.LEFT)
|
||||||
|
add_textbox(s, Inches(1.0), Inches(2.85), Inches(11), Inches(0.5),
|
||||||
|
'포트폴리오 다운로드 URL',
|
||||||
|
size=18, color=COLOR_ACCENT,
|
||||||
|
font=FONT_BODY, align=PP_ALIGN.LEFT, italic=True)
|
||||||
|
|
||||||
|
# 다운로드 카드 (예시 — 원본에 URL 텍스트 단편만 존재)
|
||||||
|
add_rect(s, Inches(1.0), Inches(3.8), Inches(11.3), Inches(0.04), COLOR_GOLD)
|
||||||
|
|
||||||
|
download_items = [
|
||||||
|
('GAME DESIGN DOCUMENTS',
|
||||||
|
'기획서 · 시스템 설계 · 밸런스 표 등 실무 작업 결과물 모음'),
|
||||||
|
('UI / UX MOCKUPS',
|
||||||
|
'발사믹·스파인·기타 목업 툴을 활용한 화면 설계'),
|
||||||
|
('SCRIPTS & SCENARIOS',
|
||||||
|
'게임 시나리오 · 멀티 시나리오 스크립트'),
|
||||||
|
]
|
||||||
|
y = Inches(4.2)
|
||||||
|
for label, desc in download_items:
|
||||||
|
add_rect(s, Inches(1.0), y, Inches(0.05), Inches(0.7), COLOR_GOLD)
|
||||||
|
add_textbox(s, Inches(1.2), y + Inches(0.05), Inches(11), Inches(0.35),
|
||||||
|
label, size=13, bold=True, color=COLOR_WHITE,
|
||||||
|
font=FONT_HEADER, align=PP_ALIGN.LEFT)
|
||||||
|
add_textbox(s, Inches(1.2), y + Inches(0.35), Inches(11), Inches(0.3),
|
||||||
|
desc, size=11, color=COLOR_ACCENT,
|
||||||
|
font=FONT_BODY, align=PP_ALIGN.LEFT, italic=True)
|
||||||
|
y += Inches(0.85)
|
||||||
|
|
||||||
|
# 푸터
|
||||||
|
add_textbox(s, Inches(1.0), Inches(6.7), Inches(11), Inches(0.4),
|
||||||
|
'THANK YOU',
|
||||||
|
size=22, bold=True, color=COLOR_GOLD,
|
||||||
|
font=FONT_HEADER, align=PP_ALIGN.LEFT)
|
||||||
|
add_textbox(s, Inches(1.0), Inches(7.1), Inches(11), Inches(0.3),
|
||||||
|
'Lee Seung-Woo · Game Designer · 2019.12.22',
|
||||||
|
size=11, color=COLOR_ACCENT,
|
||||||
|
font=FONT_BODY, align=PP_ALIGN.LEFT)
|
||||||
|
|
||||||
|
|
||||||
|
# ─────────────── 빌드 실행 ───────────────
|
||||||
|
print('Building slides...')
|
||||||
|
build_slide_01(); print(' S1 표지')
|
||||||
|
build_slide_02(); print(' S2 인덱스')
|
||||||
|
for game in GAMES:
|
||||||
|
page, num, title, subtitle, info, overviews, role, kpi, img_file = game
|
||||||
|
build_game_slide(page, num, title, subtitle, info, overviews, role, kpi, img_file)
|
||||||
|
print(f' S{page} {title}')
|
||||||
|
build_slide_16(); print(' S16 경력')
|
||||||
|
|
||||||
|
videos_p17 = [
|
||||||
|
('데빌즈',
|
||||||
|
'https://youtu.be/GZNZvpsk5WE',
|
||||||
|
'컴투스 퍼블리싱 · 인기 무료 게임 1위 (2013/11) · 액션 RPG 플레이 영상'),
|
||||||
|
('프로젝트 BC (2014)',
|
||||||
|
'https://youtu.be/maMV-lcPB3I',
|
||||||
|
'하드코어 액션 MORPG · 2D 그래픽과 멀티 시나리오 시연'),
|
||||||
|
('Spine 2D 작업 시연',
|
||||||
|
'—',
|
||||||
|
'캐릭터 애니메이션 작업 영상 (Spine 활용)'),
|
||||||
|
]
|
||||||
|
build_video_links_slide(17, 'Reference Videos · 1', videos_p17); print(' S17 영상1')
|
||||||
|
|
||||||
|
videos_p18 = [
|
||||||
|
('드래곤 헌터스',
|
||||||
|
'https://drive.google.com/open?id=1tUkQ_bOwRrx3Y4LARqRX4KFGi5vXUocv',
|
||||||
|
'GP2X · HD 버전 플레이 영상'),
|
||||||
|
('마스터 오브 던전',
|
||||||
|
'https://youtu.be/9ipP9KkBZxI',
|
||||||
|
'시나리오형 액션 RPG 플레이 영상'),
|
||||||
|
]
|
||||||
|
build_video_links_slide(18, 'Reference Videos · 2', videos_p18); print(' S18 영상2')
|
||||||
|
|
||||||
|
videos_p19 = [
|
||||||
|
('쿠로네코 프로젝트',
|
||||||
|
'https://drive.google.com/open?id=1poqqti2raZw_rosy3RJlVQNctPmEeE2P',
|
||||||
|
'개발이 상당부분 완료된 상태에서 중도 드랍된 쿠로네코 프로젝트 시연 영상'),
|
||||||
|
('학교가는 길 1',
|
||||||
|
'https://youtu.be/XMWlcZyJYSg',
|
||||||
|
'조이모아 퍼블리싱 · 학교가는 길 플레이 영상'),
|
||||||
|
]
|
||||||
|
build_video_links_slide(19, 'Reference Videos · 3', videos_p19); print(' S19 영상3')
|
||||||
|
|
||||||
|
build_slide_20(); print(' S20 마무리')
|
||||||
|
|
||||||
|
prs.save(OUT_PATH)
|
||||||
|
print(f'\n✅ Saved: {OUT_PATH}')
|
||||||
|
print(f' Size: {os.path.getsize(OUT_PATH):,} bytes')
|
||||||
|
print(f' Slides: {len(prs.slides)}')
|
||||||
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 2.2 MiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 150 KiB |
|
After Width: | Height: | Size: 477 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 848 B |
|
After Width: | Height: | Size: 862 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 848 B |