콘텐츠로 이동

플러그인 개발

메인 메뉴, 맵 관리자, 플러그인 관리자에서 Creator / Workshop을 엽니다. 단일 맵, 두 단계 캠페인, 플러그인, 관련 플러그인과 보스 튜토리얼을 만들고 오프라인에서 편집·저장·검증·시험합니다. 로컬 프로젝트, 구독, 내 게시물, 탐색기, 작업을 관리합니다. ‘왕국 미션’ 템플릿은 브리핑, 현상금, 웨이브, 이름 있는 보스를 갖춘 한 레벨짜리 kingdom 캠페인을 만듭니다.‘콘텐츠 가져오기’ 또는 작업 공간에 끌어다 놓기로 ZIP, 맵 파일, 작품 폴더를 가져옵니다. ’내보내기…’는 ZIP이나 폴더를 만들고, ’폴더 열기’는 작품의 파일을 엽니다. 둘 다 폴더를 묻고(지난번 폴더가 기본값), 같은 이름이 있으면 name-2, name-3…으로 하며, Steam이 내려받은 콘텐츠에는 쓰지 않습니다.각 작품은 미리 보기, 종류, 버전, 작성자, 이 게임에서 불러올 수 있는지, 마지막 검증 결과와 함께 표시됩니다. 모든 목록에는 검색과 종류 필터가 있고 비어 있으면 이유를 알려 주며, 선택한 작품의 상세 정보에는 라이선스, 지원 게임 버전, 필요한 것, 폴더가 나옵니다. ’새 프로젝트’는 템플릿과 각각이 만드는 것을 나열하고, 무엇이든 쓰기 전에 작품이 놓일 곳을 보여 줍니다.검증은 영웅이 성에서 걸어갈 수 없는 거점, 상자, 배치한 보스를 경고하며(승리 조건에 필요하면 오류), 한 맵을 거점 64개, 상자 256개, 배치 보스 32개 이하로 제한합니다. 지도 칸에 있는 문제를 두 번 클릭하면 그 자리에서 편집기가 열립니다.지형·캠페인 편집기는 작품의 의존 콘텐츠만 불러오는 별도 프로세스에서 열리므로, 플레이어가 설치한 다른 콘텐츠는 나타나지도 방해하지도 않습니다. 저장은 작품 자체에 합니다. 작업 공간에서 연 편집기에 저장하지 않은 변경이 있으면 검증, 내보내기, 시험 플레이, 게시는 기다립니다. 이들은 저장된 파일을 씁니다.플러그인 편집기에서 보스의 단계는 표(각 단계가 시작되는 체력과 기술)로 편집하며, 기술의 수, 상한, 예고 시간에도 각각 칸이 있습니다.플러그인 편집기는 편집할 때마다 잠시 뒤 저장하지 않은 작업의 초안을 설정 파일 옆, 작품 밖에 보관합니다. 충돌 후 프로젝트를 다시 열면 복원할지 묻습니다.플러그인 편집기에서 ’복제’는 새 ID로 정의를 복사하고, 다른 정의가 참조하는 정의는 그 참조를 없애기 전에는 삭제할 수 없으며, ’기본 콘텐츠 복사…’는 게임 액터의 완전한 사본을 원래 ID로 추가합니다. 쓰이는 곳에서 원래 정의를 대신하지만 게임의 파일은 바뀌지 않습니다.직업, 적, 건물, 거점, 연구에는 속성 양식(능력치 범위와 성장, 떨어뜨리는 골드, 가격, 건물이 모집하는 직업, 거점이 보내는 적, 연구 적용 대상)이 있어, 기반 정의에서 물려받은 값은 회색으로 보이고 게임의 범위를 벗어나거나 없는 ID를 가리키는 값은 바로 표시됩니다. 의존 항목은 표로 편집합니다.소재 탭은 끌어다 놓은 파일을 가져오고, 각 이미지의 보이는 범위를 게임의 크기·메모리 한도와 함께 보여 주며, 지형이나 아이콘으로 미리 보고, 출처와 크레디트를 보관하고, 어떤 정의가 쓰는지 나열하고 지정합니다. 이름을 바꾸면 모든 참조도 함께 바뀌고, 아직 쓰이는 파일은 제거할 수 없으며, 없는 파일을 가리키는 항목은 있는 파일로 다시 연결할 수 있습니다.시험 플레이는 불러온 내용(불러온 순서대로 각 플러그인이 추가하거나 대체한 정의, 건너뛴 플러그인과 이유)을 보여 주며 시작합니다. 작업 공간도 같은 목록을 보여 주고, 시험 중인 플러그인에서 건너뛴 정의는 문제 목록에 넣으며, 정의 표의 문제를 열면 플러그인 편집기의 그 정의로 이동합니다.

폴더/ZIP 가져오기와 편집 가능한 복사본은 새 프로젝트 ID를 만들고 자체 네임스페이스 참조를 바꿉니다. 작성자·출처·라이선스는 유지하고 원격 업데이트 연결은 상속하지 않습니다. Steam 원본은 읽기 전용입니다. 상대 경로, 크기, 배열, 트리거 순환을 검사합니다. 빈 라이선스는 재배포 허가가 아닙니다. 사본을 게시할 때 검토 화면에 출처(원본 작품, 버전, 작성자, 아이템 페이지)와 원작자의 조건이 나오며, 출처 표시를 유지하고 조건을 따른다는 것, 원본에 라이선스가 없으면 작성자의 허락을 받았다는 것을 확인해야 제출할 수 있습니다. 주어지지 않은 라이선스는 항상 공유 허락 없음으로 표시됩니다. 사본의 상세 정보에는 원본이 나오고, 구독 중인 원본이 업데이트되면 그 사실을 알려 주며, ‘로컬 편집 가능한 사본 만들기’, ‘내보내기…’, ’구독 취소’의 도움말은 각각 무엇을 하는지 설명합니다.

게시는 Steam이 필요합니다. 페이지와 미리보기를 준비하고 고정된 파일/해시 스냅샷을 검토한 뒤 명시적으로 제출합니다. 창을 닫아도 작업은 계속되고 준비 단계는 취소할 수 있습니다. 제출 후 결과가 불명확하면 작업 상태를 확인하거나 재동기화한 뒤 다시 시도합니다. 계정·App·프로젝트 ID별로 연결합니다. 미리보기는 1 MiB 미만, 자동 테스트는 모의 Steam을 사용합니다. 필수 플러그인을 먼저 게시하고 맵/캠페인 검토에서 같은 App의 항목 ID를 확인하세요. 게시 마법사는 언어별 페이지 문구와 JSON 메타데이터를 저장하고, 대표 이미지를 정사각형으로 자르며, 추가 스크린샷 최대 8장의 순서를 바꾸거나 삭제합니다. 기존 게시물은 콘텐츠를 다시 보내지 않고 페이지·의존성만 업데이트할 수 있으며 이미지도 검토 스냅샷에 포함됩니다.마법사는 작품 자체에서 주 미리보기를 만들 수 있고(지도의 지형과 성·거점·보물상자, 캠페인의 앞 레벨들, 플러그인 자체 그림에 제목을 붙임), 실제로 올라갈 미리보기와 크기를 보여 주며, 각 스크린샷 아래쪽에 설명을 그릴 수 있고, 초안이 가리키던 이미지가 없어졌으면 알려 줍니다.마법사는 세 단계(페이지, 의존 항목과 버전, 검토)를 ‘이전’·‘다음’(Alt+←, Alt+→)으로 오갑니다. 문제가 있으면 그 단계로 이동해 고칠 때까지 해당 칸을 테두리로 표시하고, 검토에서는 지난 게시 이후 추가·변경·제거된 파일 수를 보여 줍니다.실패한 작업은 어떤 종류의 문제인지(권한, 창작마당 약관, 공간, Steam 사용 중, 시간 초과, Steam 오프라인, 검사, 결과 알 수 없음, 중단), 다음에 할 일, 그리고 계정·항목·파일 이름이 없는 WS-PERM-R15 같은 코드를 알려 줍니다.’내 게시물’에서 내 항목을 고르면 공개 범위, 버전, 만든·갱신 시각, 크기, 연결된 로컬 작품, 그리고 그 작품으로 갱신할 때 바뀌는 것(페이지 항목, 파일, 필수 항목)의 목록을 보여 줍니다. 브라우저에서 항목을 고르면 설명(Steam이 제공하지 않았으면 그렇다고 표시)과 따로 구분된 두 부분을 보여 줍니다. Steam이 알려 주는 내용(종류, 필수 항목, 작성자가 허용한 게임 브랜치, 게시 때 기록된 버전, 갱신 시각, 크기, 평가)과, Steam이 설치한 뒤 항목 자체의 매니페스트가 알려 주는 내용(작품과 버전, 이 빌드가 요구된 게임 버전을 실행할 수 있는지, 필요한 작품, 바꿀 수 있는 것)입니다. Steam이 주지 않은 정보는 채워 넣지 않습니다. 구독한 항목은 Steam이 설치를 마치고 검사를 통과한 뒤에만 쓰입니다. 이 게임이 매니페스트를 읽을 수 있고, 필요한 모든 작품이 허용된 버전으로 설치되어 있으며 순환 의존이 없어야 합니다(두 항목이 같은 작품을 제공하면 내 플러그인을, 없으면 가장 오래된 항목을 씁니다). Steam이 업데이트 중인 항목은 새 버전이 설치될 때까지 설치된 버전을 계속 씁니다. 구독 탭은 구독한 모든 항목의 상태(Steam 대기, 다운로드 중과 그 바이트, 검사 대기, 사용 가능, 필요한 작품 부족, 또는 실패와 그 이유)를 보여 주고, 브라우저도 선택한 항목에 같은 상태를 표시합니다. Steam이 마치지 못한 다운로드(디스크가 가득 찬 경우 등)는 ’다운로드 다시 시도’를 누를 때까지 다시 요청하지 않습니다. 저장을 불러오기 전에 게임은 저장할 때의 콘텐츠를 확인합니다. 쓰던 작품이 업데이트·꺼짐·구독 취소되었거나 쓸 수 없을 때, 또는 다른 콘텐츠가 켜져 있을 때는 하나씩 알려 주고, 확인을 받은 뒤 저장의 보관 사본으로 불러옵니다. 불러올 수 없을 때(쓸 수 있는 사본 없음, 게임 업데이트, 다른 Steam 계정이나 앱, Steam 미실행)는 이유와 해결 방법을 알려 주며, 저장 파일과 진행 중인 게임은 그대로 둡니다. 구독 탭의 ’보관한 콘텐츠…’는 그 사본들과 의존하는 저장을 보여 주고, 확인하고, 쓰지 않는 사본을 지웁니다. 저장이 의존하는 사본은 저장 이름을 보여 주는 확인 뒤에만 지우고, 실행 중인 게임이 쓰는 사본은 지우지 않습니다. 아이템과 작품 상세 정보에는 이 게임의 버전(개발 빌드에서는 설정되지 않으며, 이때 특정 게임 버전을 요구하는 콘텐츠는 불러올 수 없음)과 Steam 브랜치도 나오고, 구독 탭의 ’항목 페이지 열기’로 쓸 수 없는 아이템을 볼 수 있습니다. 실행 중에 Steam이 다른 브랜치로 바꾸면 알림만 보여 주고 저절로 다시 시작하지 않습니다. 페이지 태그는 작품 종류에 Story, Challenge, Bosses, Classes, Enemies, Buildings, Research, Events, Languages, Art 중 원하는 것을 더한 것입니다. 페이지 단계는 작성한 페이지의 언어를 보여 주며(다른 Steam 언어는 기본 페이지를 봄), 이미 게시한 아이템은 ’Steam에서 페이지 가져오기…’로 Steam의 페이지와 초안을 항목별로 비교해 표시한 항목만 가져올 수 있습니다. Steam이 없으면 구독 아이템을 불러오지 않고 보관한 사본도 쓰지 않습니다. 둘 다 Steam 계정과 앱에 속하기 때문입니다(체험판과 정식판은 서로 다른 앱이며 각자 아이템, 초안, 콘텐츠 프로필이 있습니다). 그것이 필요한 저장은 이유를 알려 주고, 내 작품의 만들기·검사·테스트 플레이·내보내기·가져오기는 모두 오프라인으로 됩니다. 테스트 플레이가 실행되는 동안 틱 시간, 메모리, 스프라이트 아틀라스를 측정하고, 작업 공간은 이를 테스트 플레이 보고서에 괜찮음·주의·너무 무거움으로 나눠 덧붙이며 개선 방법을 알려 줍니다. 콘텐츠나 용량 때문에 업로드가 실패하면 설명에 Steam의 제한이 나오고, 완료되면 게시만으로는 확인되지 않으니 구독해서 잘 불러오는지 확인하라고 알려 줍니다. 업로드는 5분 동안 진행이 없을 때만 중단되고, 완료되었거나 취소된 작업은 1주일 뒤 목록에서 사라집니다. 새 테스트 플레이를 시작하면 실행 중인 게임이 쓰지 않는 오래된 세션은 삭제되고, 로컬 작품에서 Enter를 누르면 편집기가 열리며, 이 창들은 모든 언어에서 1280 × 720 화면에 맞습니다.

버전이 있는 플러그인은 내장 동작 템플릿으로 독립된 네임스페이스 직업, 적, 건물, 거점과 스킬, 연구, 이벤트, 이름 있는 보스, 자산, 언어를 추가합니다. 새 ID는 namespace:name이며 내장 ID를 유지하면 기존 콘텐츠를 덮어씁니다. 핵심 파일은 읽기 전용입니다. 외형 전용 스킨은 게임 수치를 유지하며 캐릭터나 지형 이미지를 바꿉니다. 플레이어 건물은 효과를 가질 수 있습니다. 공격·치유·보호막·상태 기술 하나를, 정해진 레벨에 이르면 범위 안의 적이나 영웅에게 일정한 간격으로 사용합니다. 능력이 assets와 languages뿐인 팩은 스킨(skins)과 언어만 담을 수 있고, 게임이 쓸 수 없는 그림이나 소리는 내장된 것이 그대로 쓰입니다.

공통 매니페스트에 프로젝트 ID, 작성자, 버전, 호환 범위, 자산, 의존성을 기록합니다. 새 형식은 의존 순서로 결정적으로 로드하며 누락, 충돌, 순환 시 중단합니다. 기존 형식과 순서는 유지합니다. 프로필에서 덮어쓰기를 미리 확인하고 다음 게임에 적용합니다. 콘텐츠 프로필은 선택한 플러그인을 불러오는 순서대로 보여 주며, 각각의 출처와 설치된 버전, 실행 중인 게임이 쓰는 버전, 다음에 선택된 버전을 표시합니다. ’위로’와 ’아래로’는 의존 관계가 허락할 때만 순서를 바꾸고, 순서는 같은 Steam 계정과 앱의 다음 불러오기에 적용됩니다. 적용하기 전에 켜지거나 꺼질 플러그인과, 꺼지는 플러그인을 쓰는 지도·캠페인·플러그인·저장을 보여 줍니다. 문제를 더블클릭하면 해당 플러그인을 찾고, 지도나 캠페인에 필요한 플러그인을 제안할 수 있으며, 보이지 않는 구독 항목(내 플러그인의 사본 등)은 그 이유를 알려 줍니다.

{"manifest_version":1,"format_version":1,"kind":"Plugin",
"project_id":"sample:content","namespace":"sample","version":"1.0.0",
"author":"Author","game_version":"*","entry_points":["plugin.json"],
"assets":["preview.png"],"preview":"preview.png","languages":["en"],
"capabilities":["dynamic_types","behavior_templates","bosses","assets"],
"dependencies":[],"license":"","source":{}}

content-manifest.json / <map-stem>.manifest.json

{"id":"sample","name":"Example","version":"1.0.0",
"content":{"enemies":"content/enemies.json","skills":"content/skills.json",
"bosses":"content/bosses.json","languages":["lang/en.json"]}}

plugin.json

[{"id":"sample:slime","base":"SLIME","stats":{"hp":90}}]
[{"id":"sample:strike","template":"attack","cooldown":60,"radius":5,"power":10}]
[{"id":"sample:chief","enemy":"sample:slime","name":"Chief",
"phases":[{"hp":1,"skills":[]},{"hp":0.5,"skills":["sample:strike"]}],"reward":100}]
{"bosses":[{"definition":"sample:chief","encounter":"bridge_chief","x":21,"y":16}],
"victory":"defeat_boss","victory_target":"bridge_chief"}
{"project_id":"sample:content","version":">=1.0.0,<2.0.0","optional":false}
JSON 자산과 제한
skills attack, heal, shield, status, summon
adventurer_classes.skills 직업의 스킬 트리(패시브 스킬): {"id", "level", "effect", "requires": [ids]} 목록(개수 제한 없음, 같은 레벨에 여러 개 가능) 또는 예전 방식의 표 {"<레벨>": {"id", "effect"}}(한 줄의 사슬로 읽음). id는 직업 안에서 고유하고, requires는 같은 직업의 스킬을 가리키며, 순환은 안 됨
adventurer_classes.active_skill, tree_skills 직업 고유의 액티브 스킬(같은 트리의 노드): active_skill은 첫 스킬(뿌리)의 ID, tree_skills는 트리에서 뻗는 스킬의 ID(최대 12개). 모두 skills의 스킬이며(summon 불가), 자신의 level에 이르고 requires에 적힌 스킬(직업 스킬의 ID 최대 8개, 패시브·액티브 모두 가능, 첫 스킬에는 불가)을 모두 익히면 배우고, 각자 자신의 cooldown만큼 기다림. active_skill이 없는 직업은 기반 직업의 첫 스킬을 그대로 씀
buildings.effect 공격·치유·보호막·상태 기술(소환 불가)을 건물 레벨 1–3부터 10–3600틱마다 사용, 상태는 겹치지 않음
research stat_modifier
castle_branches 성의 길: id, playable, buildings(건물 ID, 게임 기본 또는 플러그인 자체의 것), effects와 level3(효과 이름을 키로 하는 숫자, 이름은 게임 기본 길과 같음), specialities(없음, 또는 둘 이상의 {"id", "effects"}). 기본 길과 같은 ID의 정의는 그 길을 통째로 대체하고, namespace:name 형식의 ID는 길을 추가함(게임의 길 뒤에 나열되고 길을 고를 수 있는 곳이면 어디서나 제공). 문구는 언어 키 branch_<id>, branch_<id>_desc, branch_<id>_price, branch_<id>_level3, branch_<id>_heroes 와 speciality_<id>_<speciality>. 길이 더 이상 로드되지 않는 왕국은 길을 고르지 않은 것으로 플레이하며, 저장에는 선택이 남음
events gold, enemy_wave, stat_buff
bosses 1–8 phases; optional stats of its own (hp, attack, defense); a name starting i18n: is a translation key
skins tiles, adventurer_classes, enemies, buildings, enemy_buildings; 외형 전용
assets by kind adventurer_classes, enemies: animation_sheet / sprite, sound; buildings: sprite, icon; enemy_buildings: sprite; skills: skill_effect; skins tiles: sprite (불투명하게 그림); 캐릭터 스킨: 대상과 같음; 그 밖의 필드와 캐릭터 외의 layout은 쓰이지 않으며 경고됨
plugin art and sounds 켜진 모든 팩이 함께 디코딩된 이미지 256 MiB(너비 × 높이 × 4), 같은 파일은 한 번만 셈, 넘으면 내장 그림; 플러그인 소리는 메모리에 64 MiB까지 보관
capabilities: assets, languages only 스킨(skins)과 언어만, 다른 정의는 거부됨
assets.animation_sheet PNG: 24 columns × 5 rows
assets.sprite / icon / skill_effect PNG; 8192 px/side, 16 million pixels
assets.sound WAV; mono/stereo, ≤30 seconds
layout.anchor [0–1, 0–1]
effect_frames 1–64
preview <1 MiB
portable project ≤2048 files; ≤64 MiB total; ≤16 MiB/file
map ≤2048 tiles/side
campaign 레벨 맵 ≤127개
spawn_enemies.action_params.count 1–32
spawn_enemies.action_params.march castle / road
reveal.action_params.radius 1–40
post_bounty.action_params.reward 1–99999
post_bounty.action_params.deadline 0–6000 ticks
adventurer_classes.profile.explore_range 10–400
adventurer_classes.profile.retreat_hp 0.15–0.5
adventurer_classes.profile: explore / hunt / steal / flags.* / errands.* 0–3
{"id":"sample:grass","kind":"tiles","target":"GRASS",
"assets":{"sprite":"assets/grass.png"}}

PLUGINS.md

game_version은 실행 중인 게임의 출시 버전에 대한 조건입니다. 이전 프로젝트를 포함하여 "*"는 허용됩니다. 특정 범위는 빌드에 알려진 시맨틱 게임 버전이 선언되어 있고 해당 범위를 만족할 때만 허용되며, 그렇지 않으면 검증, 불러오기, 게시가 거부됩니다. 이 저장소의 game.build_info.GAME_VERSION은 현재 알 수 없으므로 출시 빌드가 승인된 버전을 제공할 때까지 "*"를 사용하세요. 프로젝트의 version과 Steam 브랜치 이름은 게임 버전을 대신하지 않습니다.