T-015에서 갈라져 나왔다 (2026-09-16). 클라가 [정렬] 버튼을 먼저 넣었지만 순서를 세션 동안만 기억한다 — 재접속하면 사라진다.
배경
인벤토리 격자는 i번째 항목을 i번째 칸에 그린다. 그런데 그 순서가 지금은 서버가 보내 준 목록 순서다. 사람이 정한 자리가 아니라서, 정렬해도 다시 접속하면 원래대로 돌아가고 드래그로 옮길 수도 없다.
칸 위치를 서버가 들고 있어야 재접속·다른 기기에서도 자리가 유지된다. 클라가 저장하면(PlayerPrefs 등) 계정과 기기가 어긋나는 순간 조용히 틀린다.
지금 패킷에는 위치가 없다 — ItemInfo { ItemId, Count }, CharacterInfo { CharacterId, CharacterTid, … }.
정렬 기준 셋 (2026-09-20 추가)
원래 이 일감의 정렬은 클라 임시 정렬과 같은 규칙 하나였다. QA 피드백으로
'이름순'·'보유 수량순' 이 더해져 기준이 셋이 됐다 —
자원이 150종을 넘어 등급 하나로는 찾을 수가 없다
(0920-피드백 및 답변 정리.md 2번).
기준 자체는 클라가 먼저 넣는다 → T-073. 줄 세우는 것은 받아 둔 목록을 다시 정렬하는 것이라 서버가 필요 없다. 이 일감이 맡는 것은 "그 순서가 재접속해도 남는가" 다 — 지금은 로그인할 때 버려서(세션 한정) 껐다 켜면 원래대로 돌아간다. 그래서 여기서 정할 기준 목록은 T-073과 같아야 한다 — 다르면 서버 정렬을 켠 순간 순서가 바뀐다. (찾기(검색·필터)도 서버 없이 클라만으로 간다 → T-069.)
2026-09-25 — 클라가 먼저 같은 규칙으로 움직인다
장착·배치로 개체가 빠질 때 뒤의 것이 앞으로 당겨지던 문제를 클라에서 고쳤다(T-044). 지금 클라는 떠난 칸을 비워 두고, 들어오는 것은 앞에서부터 첫 빈 칸에 넣는다 — 다만 세션 한정이다.
서버 규칙을 여기에 맞춰 주셔야 한다 — 아래 "새 항목은 첫 빈 칸에 둔다"와 같은 규칙이다. 다르면 서버 위치를 켜는 순간 자리가 한 번 뒤집힌다. ⚠️ 장비만
EquipInfo.SlotPosition이 이미 있는데, 클라는 그것을 칸 번호로 쓰지 않는다(도착 순서로만). 자원·캐릭터에 같은 필드가 없어 세 탭의 자리 규칙이 갈라지기 때문이다 — 세 탭을 같은 필드·같은 규칙으로 함께 옮겨 주셔야 한다. ※ 장착 중인 장비도 인벤토리 칸을 그대로 차지한다(2026-09-25 결정) — 서버가SlotPosition을 비우지 않는 지금 동작이 맞다. 비우면 안 된다.
할 일
2026-10-01 서버 완료 — 설계
Server/docs/인벤토리-창고.md· 계획2026-10-01-T-058-칸위치.md. 칸은 개체가 든다(Item.Slot·Character.Slot·Equip.SlotPosition), 계산은 순수 함수StorageSlots·StorageSort. 인벤토리 50칸과 별도 보관소 창고는 T-107로 넘어갔다 — 이 일감의container컬럼이 그 자리를 이미 잡아 뒀다.
- [x] 칸 번호 필드 —
ItemInfo·ItemChangeInfo·CharacterInfo에Container·Slot,EquipInfo에Container - [x] DB 컬럼 —
t_user_inventory는 PK(user_id, container, item_id)로 다시 만들고slot추가,t_character에container·slot,t_user_equip에container. 기존 데이터는 ID 순으로 0부터 (Server/Shared/migrations/2026-10-01-storage-slot.sql) - [x] 스냅샷과 증분 푸시에 칸 번호를 싣는다 — 모든 자원 저장이
ItemChangeInfo.Slot을 그대로 쓴다 - [x] 새 항목은 첫 빈 칸 — 채취·뽑기·치트·우편 캐릭터 수령(#47)까지. 캐릭터는 장비처럼 지급 전에 칸을 예약한다(연속 뽑기 겹침 방지)
- [x] 수량이 0이 된 자원의 칸 — 행을 지우고 칸을 비운다(기존 동작 그대로). 다음 새 자원이 그 칸을 쓴다
- [x] 정렬 요청
C_StorageSortRequest { Container, Tab, SortKey, Order }— 클라CompareByRule과 같은 규칙. ⚠️ 오름차순은 규칙 전체를 뒤집고, 배치·장착 중인 것은 방향과 무관하게 맨 뒤(클라 코드 대조로 확정) - [x] 자리 이동 요청
C_StorageMoveSlotRequest— 빈 칸이면 이동, 차 있으면 교환. 응답S_StorageSlotsResponse - [x] 거절 코드 —
StorageSlotOutOfRange(1100) ·StorageSlotEmpty(1101) ·InvalidStorageSortKey(1102) ·StorageSlotPending(1103 — 도착 칸이 지급 대기로 예약됨) - [x] 테스트 — 칸 계산·정렬 순서·자원 칸·캐릭터 예약·저장 SQL·재로그인·이동·정렬 (전체 721 통과)
- [x] 프로토콜 미러 커밋 —
d42cc04 - [x] 실서버 확인 (2026-10-01, 더미 클라 · 계정
test) — 이동 0→10 저장 · 재로그인 후 10 유지 · 등급 정렬 후 0~5 촘촘히 · 칸 0을 비우고 치트 지급한 새 자원이 칸 0 - [x] 클라(T-044)와 맞물려 확인 — 2026-10-06 사용자 실측(이동 · 교환 · 정렬 · 재접속 유지)
완료 조건
더미 클라이언트로 정렬·자리 교환을 보낸 뒤 재로그인해도 스냅샷의 칸 번호가 그대로이고, 새로 채취한 자원이 첫 빈 칸에 들어간다. Unity 미러가 커밋돼 클라 컴파일이 깨지지 않는다.
막고 있는 것 / 선행 일감
- 없음
관련 커밋
13bc73e·0223dd5— 설계 · 계획39cde95— 칸 계산 순수 함수3088d4a— 정렬 순서d42cc04— 패킷 · Unity 미러ee920cb— 자원 칸ff42f75— 캐릭터 칸 · 지급 예약 · 우편 수령b461323— DB 마이그레이션 · 저장 SQL9aac60c— 자리 이동 요청3c09ee0— 정렬 요청8f3c345— 더미 클라 메뉴2d89897— 재로그인 테스트의 전역 UserManager 누수 수정 (T-089 빈도)07568fc— 리뷰 반영: 지급 대기 칸을 정렬·이동이 덮지 않게- 클라 T-044 커밋 — 클라 연동 확인으로 완료 (2026-10-06)
참고
- 클라 임시 정렬:
Assets/Scripts_Client/UI/Inventory/InventoryGridPresenter/InventorySlotSource.cs(Sort·_rank) — 규칙은ResourceSlotSource·CharacterSlotSource의CompareForSort - 이 일감이 끝나면 클라 T-044가 임시 기억을 걷어내고 서버 위치로 바꾼다
Server/MikaProtocol/MikaPacket.cs·Server/MikaProtocol/PacketInfo.cs(ItemInfo·CharacterInfo)