[뒤끝탐사대] 예시로 알아보는, 뒤끝 차트 A to Z

안녕하세요! 개발이 필요 없는 게임서버, 뒤끝입니다.

뒤끝 개발자 분들이 필수로 사용하는 기능을 알고 계신가요?✨ 바로 ‘차트 관리’입니다.

🙋‍♀️ 게임 데이터를 저장하고 불러오고 수정하는 방법이 궁금하신 분?
🙋‍♀️ 보스 공격력을 낮추고 스테이지 난이도를 조정하고 싶은 분?
🙋‍♀️상점의 아이템 이름에서 오타를 발견해 빠르게 고쳐야 하는 분?

위 같은 고민을 하고 계시다면, 오늘 주목해 주세요.

목차 한눈에 보기👀

✅ 차트 관리 기능이란?

[차트 관리] 기능은 게임에서 모든 유저들이 공통적으로 사용하게 되는 데이터를 저장하고, 불러올 수 있도록 만든 기능입니다. 

유저들이 공통적으로 사용하는 데이터에는 어떤 것들이 있을까요? 바로 ‘상점의 아이템 정보’, ‘퀘스트 정보’, ‘몬스터 정보’ 등이 포함됩니다. 

뒤끝에서는 이런 정보들을 아래와 같이 익숙한 엑셀 파일(xlsx, xls, csv) 형태로 업로드할 수 있는데요. 여기서 업로드한 것을 ‘차트 파일’이라고 부릅니다😊

차트 파일 작성 예시
차트 파일 예시 - enemyChart.csv

위 같은 차트 파일을 뒤끝 콘솔에 업로드해 주시면, 필요할 때마다 콘솔을 통해 편하게 수정이 가능합니다. 업로드 방법도 복잡할 것 없이 아주 간단합니다.

✊'아주 간단한' 차트 파일 업로드 방법

1. [뒤끝 콘솔] - [차트 관리] 메뉴로 들어가 '차트 생성'을 클릭하면 차트가 생성됩니다.
2. 생성된차트를 클릭하고, 상단의 '차트 파일 업로드'를 클릭해 줍니다.
3. 필요한 데이터로 구성된 차트 파일을 선택해 업로드합니다.

📥 업로드한 데이터를 SDK에서 받는 방법

위 방법대로 차트 파일을 콘솔에 업로드하면, 아래와 같이 각 차트마다 고유한 파일 ID가 부여됩니다.

뒤끝 콘솔 차트 관리 UUID
부여받은 고유한 '파일 ID'

그리고 이 파일 ID를 차트 내용 조회 함수의 인자 값으로 이용하여, 해당 차트 파일의 데이터를 JSON으로 SDK에서 받을 수 있습니다. 아래는 위 이미지에서 2번 데이터의 파일 ID를 차트 내용 조회 함수의 인자 값으로 이용한 예시입니다.

차트 내용 조회 함수

해당 함수의 자세한 사용법은 가장 뒤에 나오는 ‘실제 활용 사례’ 목차를 확인해 주세요!

				
					Backend.Chart.GetChartContents("72710");
				
			

*더 자세한 사용법이 궁금하시다면 〈뒤끝 개발자|차트 내용 조회〉문서를 참고해 주세요!

차트 내용 조회 함수의 리턴값

				
					{
  "rows": [
    {
      "EnemyID": {
        "S": "1"
      },
      "EnemyName": {
        "S": "클라우드 기사"
      },
      "Hp": {
        "S": "100"
      },
      "Lv": {
        "S": "1"
      },
      "Exp": {
        "S": "10"
      },
      "Money": {
        "S": "1001"
      },
      "DropItemList": {
        "S": "null"
      },
      "Image": {
        "S": "Enemy1"
      }
    },
    {
      "EnemyID": {
        "S": "2"
      },
      "EnemyName": {
        "S": "클라우드 남작"
      },
      "Hp": {
        "S": "120"
      },
      "Lv": {
        "S": "2"
      },
      "Exp": {
        "S": "14"
      },
      "Money": {
        "S": "1400"
      },
      "DropItemList": {
        "S": "[{\"id\":\"1\", \"percent\":\"20\"}]"
      },
      "Image": {
        "S": "Enemy2"
      }
    },
    ...
}
				
			

✍️ 데이터를 손쉽게 수정하는 방법

가장 간단한 방법은 ‘뒤끝 콘솔에서 바로 수정하기’입니다. 

아래는 글 첫 부분에서 예시로 들었던 ‘enemyChart.csv’ 차트 파일이 콘솔에 업로드된 모습입니다.
여기서 ‘편집 모드’를 on으로 변경하면 바로 데이터를 수정할 수 있습니다.

뒤끝 콘솔 실시간 편집 모드
데이터를 수정할 수 있는 '편집 모드'

그러나 이 방법은 간단한 만큼, 데이터를 수정하는데 아래와 같은 큰 제약이 따릅니다.

🚨뒤끝 콘솔로 차트, 위 화면에서 어디까지 수정 가능할까?

▪️ 가능한 것: only 기존 레코드 '삭제하기'
▪️ 불가능한 것: 새로운 레코드와 컬럼 '추가하기'

*레코드와 컬럼이 어렵다면 〈효율적인 데이터 저장을 위한, DB 기초 지식〉을 참고해 주세요!

예를 들어 게임에 신규 몬스터를 추가해야 한다면, 기존 차트를 수정하기보다 해당 몬스터의 레코드가 추가된 새로운 차트 파일을 업로드해야 합니다. 

그런데 새 차트 파일을 업로드하고, 게임에 반영되도록 하는 과정은 아주 번거롭습니다.

스크립트에는 이미 파일 ID가 “72710”으로 하드코딩 되어있기 때문에, 결론적으로 앱을 스토어에 업로드하고 유저가 업데이트하게끔 안내해야 하기 때문입니다. 풀어서 설명하면 ①신규 몬스터의 데이터가 추가된 차트 파일을 콘솔에 업로드하고, ②새로 부여된 파일 ID를 스크립트에 넣어준 후, ③앱을 스토어에 다시 업로드하는 과정을 거치는데요.

바로 이때! [차트 리스트 조회] 함수가 빛을 발합니다. ✨

아래와 같이 차트 리스트를 불러오고, 해당 차트 이름에서 리턴하는 차트 파일 ID를 사용한다면 차트 적용 버튼을 통해 어떤 차트로도 손쉽게 변경이 가능합니다.

차트 리스트 조회 함수

🚨주의할 점

위에서 나왔던 '차트 내용 조회(Backend.Chart.GetChartContents)'와는 다른 함수입니다.
이름이 비슷하기 떄문에, 혼동에 주의해 주세요! 😃

				
					Backend.Chart.GetChartList();
				
			

*더 자세한 사용법이 궁금하시다면 〈뒤끝 개발자|차트 리스트 조회〉문서를 참고해 주세요!

이 함수는 뒤끝 콘솔에 업로드된 차트의 리스트 중 필요한 파일을 불러오는 기능입니다. 
그리고 불러온 데이터에는 생성한 차트의 현재 적용 차트 ID가 노출됩니다.

아까 가정한 대로 게임에 신규 몬스터를 추가해야 한다면, 해당 데이터가 추가된 차트파일을 선택하고 상단의 ‘✅차트 적용’ 버튼을 클릭해 줍니다. 그러면 현재 적용 차트가 변경이 되므로, 앱을 재업로드할 필요 없이 GetChartList의 리턴값이 바뀌면서 코드 변경 없이 차트를 변경할 수 있습니다.

코드 변경 없이 바로 차트 적용
[뒤끝 콘솔] - [차트 관리] - 차트명(EnemyChart) 클릭 화면

차트 리스트 조회 함수의 리턴값

				
					{
  "rows": [
    {
      "chartName": {
        "S": "StageChart"
      },
      "chartExplain": {
        "NULL": true
      },
      "selectedChartFileId": {
        "N": "72709"
      },
      "old": {
        "S": "n"
      }
    },
    {
      "chartName": {
        "S": "EnemyChart"
      },
      "chartExplain": {
        "NULL": true
      },
      "selectedChartFileId": {
        "N": "72710"
      },
      "old": {
        "S": "n"
      }
    },
    ....
  ]
}
				
			

차트 리스트를 불러와 File ID에 접근하는 로직

				
					var bro = Backend.Chart.GetChartList();

Dictionary<string, string> chartInfoDictionary = new Dictionary<string, string>();

foreach (JsonData chartData in bro.FlattenRows()) {
	string chartName = chartData["chartName"].ToString();
	string chartFileId = chartData["selectedChartFileId"].ToString();
	
	chartInfoDictionary.Add(chartName, chartFileId);
}

bro = Backend.Chart.GetChartContents(chartInfoDictionary["EnemyChart"]);
				
			

📒 실제 활용 사례

마지막으로, 뒤끝 방치형 예제 게임을 예시로 차트 관리 기능을 알아보겠습니다.

해당 프로젝트의 콘솔에는 아래와 같이 적 정보, 스테이지 정보, 퀘스트 정보 등의 데이터가 담긴 차트가 등록되어 있습니다.

뒤끝 콘솔의 여러 차트들

위 차트들은 유저가 ①로그인을 하면, ②모든 차트를 읽어온 후 ③데이터를 List 혹은 Dictionary 형태로 파싱하여 UI에 표시합니다. 

예제 게임 로그인 화면
①로그인
예제 게임 데이터 로딩 화면
② 모든 차트를 읽어오기
데이터를 파싱하여 UI에 표시
③데이터를 파싱하여 UI에 표시

적 정보는 다음과 같이 파싱됩니다.

EnemyInfo 클래스

				
					class EnemyInfo {
			public string enemyId ;
			public string enemyName;
			public string hp;
			public string lv;
			public string money;
		}
				
			

List로 이용

				
					var bro = Backend.Chart.GetChartContents("12345");

			if (bro.IsSuccess() == false) {
				return;
			}

			List<EnemyInfo> enemyInfos = new List<EnemyInfo>();

			foreach (JsonData enemyData in bro.FlattenRows()) {
				EnemyInfo enemyInfo = new EnemyInfo();

				enemyInfo.enemyId = enemyData["EnemyID"].ToString();
				enemyInfo.enemyName = enemyData["EnemyName"].ToString();
				enemyInfo.hp = enemyData["Hp"].ToString();
				enemyInfo.lv = enemyData["Lv"].ToString();
				enemyInfo.money = enemyData["Money"].ToString();

				enemyInfos.Add(enemyInfo);
			}
				
			

Dictionary로 이용

				
					var bro = Backend.Chart.GetChartContents("12345");

			if (bro.IsSuccess() == false) {
				return;
			}

			Dictionary<string, EnemyInfo> enemyInfoDictionary = new Dictionary<string, EnemyInfo>();
			foreach (JsonData enemyData in bro.FlattenRows()) {
				EnemyInfo enemyInfo = new EnemyInfo();

				enemyInfo.enemyId = enemyData["EnemyID"].ToString();
				enemyInfo.enemyName = enemyData["EnemyName"].ToString();
				enemyInfo.hp = enemyData["Hp"].ToString();
				enemyInfo.lv = enemyData["Lv"].ToString();
				enemyInfo.money = enemyData["Money"].ToString();

				enemyInfoDictionary.Add(enemyInfo.enemyName, enemyInfo);
			}
				
			

위 방법으로 파싱을 끝내고, Dictionary와 List로 새롭게 탈바꿈한 데이터들은 로컬에서도 쉽고 빠르게 접근할 수 있게 됩니다! 🎉

✨ 진짜 실전 코드

아래 뒤끝 방치형 예제 게임에서 실제로 사용하는 차트 파싱 코드를 공유드립니다.

				
					public class Item {
    public class DropItem {
        public int ItemID { get; private set; }

        public float DropPercent { get; private set; }

        public DropItem(int itemID, float dropPercent) {
            ItemID = itemID;
            DropPercent = dropPercent;
        }
    }

    public int EnemyID { get; private set; }
    public string EnemyName { get; private set; }

    public float Hp { get; private set; }
    public int Lv { get; private set; }
    public float Exp { get; private set; }
    public float Money { get; private set; }
    public List<DropItem> DropItemList { get; private set; }
    public string Image { get; private set; }
    public Sprite EnemySprite;

    public Item(JsonData json) {
        EnemyID = int.Parse(json["EnemyID"].ToString());
        EnemyName = json["EnemyName"].ToString();
        Hp = float.Parse(json["Hp"].ToString());
        Lv = int.Parse(json["Lv"].ToString());
        Exp = float.Parse(json["Exp"].ToString());
        Money = float.Parse(json["Money"].ToString());
        Image = json["Image"].ToString();

        DropItemList = new List<DropItem>();

        string dropItemListString = json["DropItemList"].ToString();

        if (string.IsNullOrEmpty(dropItemListString) || dropItemListString == "null") {
            return;
        }
        
        JsonData dropItemListJson = JsonMapper.ToObject(dropItemListString);

        foreach (JsonData item in dropItemListJson) {
            int itemID = int.Parse(item["id"].ToString());
            float percent = float.Parse(item["percent"].ToString());
            DropItemList.Add(new DropItem(itemID, percent));
        }
    }
}
				
			
				
					Dictionary<int, Item> enemyInfoDictionary = new();

var bro = Backend.Chart.GetChartContents("71710");

if(bro.IsSuccess() == false) {
  return;
}

foreach (JsonData eachItem in bro.FlattenRows()) {
    Item info = new Item(eachItem);

    enemyInfoDictionary.Add(info.EnemyID, info);
 }
				
			

차트 관리 기능은 뒤끝에서 가장 사랑받고 있는 기능 중 하나이지만, 잘 알고 사용했을 때 가장 효용이 큰 기능이기도 합니다.

위 예시처럼 JSON 사용에 대해 조금만 인지하시면, 쉽게 사용이 가능한 기능입니다.
뒤끝 차트 관리 기능을 통해 게임 운영의 난이도를 한 단계 낮춰 보세요😊

1

댓글