Tictim과 함께하는 마인크래프트 모딩 101

단편-1. I18n


※ 이 강좌는 1.10 ~ 1.11버전을 기준으로 작성됩니다.


틱팀입니다.

오늘은 모 지인 분께서 I18n에 대한 이해도가 아주 테러블한 것을 보고 충격을 받아서 I18n에 대한 짧은 설명과, 자세한 사용법을 알려드리도록 하겠심미다.


1. 현지화란?


현지화(Localization)란, 프로그램을 여러 문화권의 사람들이 사용할 수 있도록 지원하는 것을 의미합니다. 마인크래프트에서는 주로 번역을 가리키죠.


마인크래프트에서 번역을 하는 원리는 다음과 같습니다. lang 파일이라는 문자열 두 개를 =으로 묶어 놓은 문자열의 쌍으로 이루어진 텍스트 파일이 있습니다. 게임에서 설정된 언어에 따라서 lang 파일을 읽어 문자열의 쌍을 저장해 둡니다.

그리고 특정한 클래스에서 번역될 문장의 키 값을 입력하면, 첫 번째 문자열이 키 값과 일치하는 문자열 쌍을 찾아 그 쌍의 두 번째 문자열을 반환합니다.

사진으로 설명하면 이렇습니다.


2. I18n


마인크래프트에서 번역을 지원하는 클래스는 두 종류가 있습니다. 둘 다 비슷한 방식으로 작동하긴 합니다. 하나는 I18n, 다른 하나는 I18n입니다.


..

..

네. 똑같은 이름의 클래스가 두 개나 있습니다. 하는 일은 똑같지만 알아둬야 할 차이점이 있으니 숙지하세요.


 

(Client-Sided)

I18n

[ net.minecraft.client.resources.I18n ]

(Deprecated)

I18n

[ net.minecraft.util.text.translation.I18n ]

서버에서 존재

 아니오

 예

포매팅 없는 번역

 불가

 가능

Fallback(영어 고정) 번역

 지원 안 함

 지원


어째 client.resources.I18n이 더 구려 보입니다. 말만 Deprecated지, 바닐라에서도 특수한 상황이 아니면 util.text.translation.I18n을 씁니다. 클라이언트에서만 존재한다는 게 꽤나 큰 제약이거든요. 그런 이유로 여러분도 후자를 더 많이 쓰게 될 겁니다.


여담이지만 client.resources.I18n에서는 포매팅 없는 번역을 아주 쉽게 구현 가능한데, 이를 하지 않은 이유가 매우 궁금해집니다. 그냥 발로 만들어 버린 걸까요. 모르겠습니다.



이번에는 I18n 클래스의 접근 가능한 함수들을 알아봅시다. 함수를 알아야 쓰죠. 그렇죠?

먼저 util.text.translation.I18n을 알아봅시다.


@Deprecated public static String translatedToLocal(String)

문자열을 번역합니다. 위에서 봤던 사진처럼, 키 값을 대응되는 문자열로 반환합니다.

대응되는 문자열이 없을 시 키 값을 그대로 반환합니다.


@Deprecated public static String translatedToLocalFormatted(String, Object...)

문자열을 번역하고, 그 결과물을 포매팅합니다. String#format을 사용합니다.

대충 이런 방식으로 작동합니다. 번역된 문자열을 키 값으로 해서 포매팅을 합니다.

포매팅 과정에서 예외가 일어나면, "Format error: "+(번역된 키 값)을 반환합니다.


@Deprecated public static String translatedToFallback(String)

쓸 데는 거의 없을 겁니다. 문자열을 en_us, 즉 영문으로 번역합니다.


@Deprecated public static boolean canTranslate(String)

I18n이 해당 키 값에 대응되는 문자열을 가지고 있는지 반환합니다. 역시 쓸 데는 거의 없을 겁니다.


@Deprecated public static long getLastTranslationUpdateTimeInMilliseconds()

I18n이 가장 최근에 업데이트된 시간을 밀리초 단위로 반환하는 것 같습니다. 쓸 데는 없습니다. 바닐라에서도 단 한 곳에서 I18n이 업데이트되었는지 여부를 체크할 때 쓰며, 이외에는 쓰이는 곳이 없습니다.


예제입니다. 강좌 2편에서 "item.item_first.name"을 "첫 번째 아이템"으로 지정한 lang파일을 그대로 사용합니다.


formattedName이라는 키를 하나 더 추가했습니다.


다음과 같은 구문을 preInit, init 아니면 아무 데에나 집어넣어 실행시켜 봅시다.


짜잔


이번에는 client.resources.I18n을 알아봅시다.


public static String format(String, Object...)

문자열을 번역하고, 그 결과물을 포매팅합니다. String#format을 사용합니다.

이전 클래스의 translatedToLocalFormatted와 같은 기능입니다.


public static boolean hasKey(String)

I18n이 해당 키 값에 대응되는 문자열을 가지고 있는지 반환합니다.

이전 클래스의 canTranslate와 같은 기능입니다.


이번에는 이 클래스를 사용하여 번역해 봅시다. 서버에서는 존재하지 않기 때문에, 저 문장은 프록시에서 실행해야 합니다. 클라이언트에서는 잘 돌아가니 결과물 나오는 것만 보고 지우도록 합시다.


짜잔


1.7에서는 net.minecraft.util.text.translation.I18n없습니다!

그 대신 똑같은 기능을 포함하는 StatCollector [ net.minecraft.util.StatCollector ] 라는 클래스가 있습니다. 그냥 이름하고 패키지만 바뀐 같은 클래스여서 다른 설명은 필요는 없을 듯 합니다.

net.minecraft.client.resources.I18n은 멀쩡히 존재합니다.



3. TextFormatting


TextFormatting [ net.minecraft.util.text.TextFormatting ] 은 마인크래프트의 텍스트 렌더러에게 주는 사인 같은 겁니다. 이걸로 글씨의 색깔을 하얗게 하거나 빨갛게 하거나 기울이거나 밑줄을 긋거나..하는 일이 가능합니다.


마인크래프트의 포매팅은 16개의 색깔과 6개의 포맷 코드를 지정할 수 있습니다. 아니, 포맷 코드 중 하나는 초기화 코드이니 사실상 5개일까요?


모든 포매팅들은 \u00a7(§)라는 문자 뒤에 한 글자를 붙인 식으로 되어 있습니다. String#format의 %s %d %f 등의 사인과 같이 말이죠.


마인크래프트가 문자열을 렌더링할 때 포매팅 코드를 읽으면, 다음부터 출력되는 문자들에 포매팅 코드에 따른 처리를 해 줍니다. 예를 들어 붉은 색을 입히는 코드 §c가 들어간 "§c빨간색"이라는 문자열을 렌더링한다면, §c를 읽은 뒤의 문자열에 붉은 색을 입혀서 결과물은 "빨간색"이 됩니다.


색깔 코드는 0부터 f까지의(16진수) 모든 글자를 붙여서 만들 수 있으며, 각각 이렇게 됩니다.

§0 -> Black

§1 -> Dark Blue

§2 -> Dark Green

§3 -> Dark Aqua

§4 -> Dark Red

§5 -> Dark Purple

§6 -> Gold

§7 -> Gray

§8 -> Dark Gray

§9 -> Blue

§a -> Green

§b -> Aqua

§c -> Red

§d -> Light Purple

§e -> Yellow

§f -> White


포맷 코드는 k, l, m, n, o, r이 존재하며, 다음과 같습니다.

§k -> 난독화. 글자를 그릴 때마다 임의의 글자를 그려서 정신없이 바뀌는 문장을 만듭니다(..)

§l -> 볼드체(굵게)

§m -> 취소선

§n -> 밑줄

§o -> 이태릭(기울임꼴)

§r -> 모든 포매팅 해제


이것들을 응용해보자면, "§c§l빨간색§r검은색"이라는 문장을 렌더링하면 "빨간색검은색"이 됩니다.


예제입니다. 우리 두 번째 아이템의 이름을 노랗게 물들여 봅시다.


짜잔



포매팅을 사용할 때 주의할 점이 있습니다. 색깔 코드를 입력받으면, 이전에 가지고 있던 포맷 코드는 사라진다는 점입니다.

예를 들어 "§o기울임체§c빨간색"이라는 글자를 그릴 때, 기울임체까지는 정상적으로 적용되지만 §c를 읽어들일 때 기존에 가지고 있던 §o에 대한 기록을 날려버리기 때문에 "기울임체빨간색"처럼 되어 버립니다.

붙어 있어도 마찬가지입니다. "§o§c기울임체와 빨간색"이라는 글자를 그릴 때, 기울임체 바로 다음 들어온 빨간색이 기울임체를 먹어 버리기 때문에 "기울임체와 빨간색"이 됩니다.

첫 번째 문장의 에러를 해결하려면  "§o기울임체§c§o빨간색"처럼 색깔 코드 이후 적용할 포맷 코드를 다시 입력해 주셔야 합니다. 두 번째 문장의 에러를 해결하려면, 순서를 바꿔 "§c§o기울임체와 빨간색"처럼 색깔을 맨 먼저 입력해 주셔야 합니다. 


그리고 TextFormatting [ net.minecraft.util.text.TextFormatting ] 이라는 이름의, 모든 포매팅 코드를 열거형으로 나열해 놓은 enum 클래스가 있습니다. 이것들은 toString()으로 변환하면 각각의 포매팅 코드가 됩니다. 예를 들어, TextFormatting.DARK_BLUE.toString()은 짙은 파란색으로 색깔을 바꾸는 코드 "§1"과 같습니다.


+

포매팅 코드 §를 빠르게 그리는 초간단 방법!

Alt 누르고 넘버 패드에서 0167. 참 쉽죠?



1.7에서는 TextFormatting이 존재하지 않습니다!

대신 EnumChatFormatting [ net.minecraft.util.EnumChatFormatting ] 이 이름과 패키지만 바뀐 채 똑같은 기능을 지원합니다.





공지 목록


[TTMP에 관심이 있으신 분들께 드리는 말씀]


[코노조에 어서오세요]


Posted by Tictim indie.