한눈에 보기
- 무엇: 자바스크립트로 게임 규칙을 바꾸는 스크립트 API(행동 팩 애드온), 게임 채팅을 내 컴퓨터 프로그램과 잇는 웹소켓
- 누구: 교사 연수, 중·고등학생 코딩 동아리 (초등은 교사 시연과 “AI에게 이런 스크립트를 요청할 수 있다” 소개 정도)
- 시간: 개발 환경 + 첫 채팅 명령어 1차시, 이벤트·타이머·UI 예제 각 1차시, 웹소켓·코드작성기 시연 20~30분
- 결과물: 채팅 명령어 애드온(.mcaddon), 블록 캐기 점수·카운트다운 타이머·순간 이동 창, AI가 답하는 채팅
- 이 페이지는 시작하기 묶음: 서버 운영·상점·아이템·PvP 예제는 맨 아래 ‘더 보기’의 하위 페이지에서
스크립트 API와 애드온
- 애드온: 행동 팩(게임 규칙)과 리소스 팩(모양·소리)으로 나만의 게임·월드를 설계하는 방법
- 스크립트 API: 행동 팩에 넣은 자바스크립트 파일(
scripts/main.js)로 기능을 만드는 방법 — 거의 무엇이든 만들 수 있을 만큼 자유도가 높음 - 함수와 차이: 함수(.mcfunction)로 만든 채팅 명령은 앞에
/function을 붙여야 하지만, 스크립트는 정해 둔 말만 채팅에 치면 됨 - 모듈:
@minecraft/server(월드·이벤트·명령 실행),@minecraft/server-ui(창·버튼) —manifest.json의 dependencies에 버전을 적음 - 공식 문서는 어렵고 문법이 자주 바뀜 → 예제 코드를 복사해 쓰거나, AI에게 공식 문서 주소를 함께 주며 코드를 받음
개발 환경: Bridge 프로젝트와 월드 설정
- Bridge 새 프로젝트 → Behavior Pack, Experimental Gameplay의 Beta APIs 켜기, 이름 적기
scripts/main.js에 코드,manifest.json에 모듈 버전 — 지금은 코드 편집을 AI 편집기에 맡김(아래)- 크리에이티브 새 월드 → 행동 팩에서 만든 팩 활성화 → 실험 기능 → 베타 API 켜기
- 설정 → 제작자 → 콘텐츠 로그 켜기, main.js 첫 줄
console.warn("불러옴")이 로그에 보이면 성공 - 코드를 고치면 Ctrl+S → 게임에서
/reload(월드를 나갈 필요 없음)


교사용 메모 · 개발 환경 메모
- Bridge: 설치하거나 웹 에디터로 열기 → 새 프로젝트(Create Project). 리소스 팩은 기본으로 켜진 그대로 둬도 됩니다. Beta APIs는 스크립트 모듈을 manifest에 넣어 줍니다.
- Project Name 적기, Project Target Version 확인(2023 영상: 1.20.40) — 교육용 에디션에 쓸 때는 쓰는 교육용 에디션의 게임 버전 이하로 낮춥니다.
- 월드의 실험 기능 ‘베타 API’ 설명은 “추가 기능 팩에서 API 모듈의 "-beta" 버전 사용”. 필요하면 홀리데이·예정된 크리에이터 기능도 켭니다.
- 설정 → 제작자의 콘텐츠 로그 옵션: 콘텐츠 로그 파일 사용 / 콘텐츠 로그 GUI 사용 / 불러오기 중 콘텐츠 로그 GUI 오류 발생.


오류가 나면: manifest 버전 맞추기
- 스크립트를 못 불러오면 로그에
requested invalid version과Available versions:(사용 가능한 버전)가 나옴 - 그 버전으로
manifest.json의 dependencies를 고쳐 저장 → 월드를 나갔다 다시 들어가기 - 2026-01 영상:
2.0.0-beta를 요청해 오류, 로그의 현재 beta는2.5.0-beta(사용 가능: 0.1.0, 1.19.0, 2.4.0, 2.5.0-beta, 3.0.0-alpha) → 로그 값으로 고쳐 해결(server-ui는 자막 기준 2.1 베타로 고침, 02:11) - 영상마다 달랐던 값: 2023-11 server
1.7.0·server-ui1.2.0/ 2025-01 server1.17.0-beta·server-ui 1.4 / 2026-012.x→ 값을 외우지 말고 로그를 보고 맞추기


지금 방식: Bridge + AI 편집기
- 2026년 영상부터 Bridge는 애드온 뼈대까지만, 코드는 AI 통합 개발 환경(구글 안티그래비티)이 작성
- Open Folder로 개발 중인 행동 팩 → Add Folder to Workspace로 리소스 팩 → Save Workspace As로 저장
- main.js를 열고 “간단한 채팅명령어 코드를 작성해줘.” + 레퍼런스 주소(공식 문서·Bedrock Wiki·JaylyDev 문서) → 파란 Accept
- 오류가 나면 로그를 보여 주며 “레퍼런스를 참고해 고쳐 줘”, 모르는 코드는 설명을 요청

AI가 만든 두 가지 채팅 명령어
- AI가 두 방법을 모두 만듦: 슬래시 명령
/scriptevent(공식 권장) +!로 시작하는 채팅 메시지
| /scriptevent 명령 | ! 채팅 명령 |
| `cmd:help` 도움말 · `cmd:hello` 인사 | `!help` 도움말 · `!hello` 인사 |
| `cmd:time` 현재 게임 시간 · `cmd:pos` 현재 위치 | `!say <메시지>` 전체 메시지 · `!tp |
| `cmd:heal` 체력 회복 | `!gamemode <모드>` 게임 모드(creative/survival) |

교사용 메모 · AI가 만든 코드 (앞부분)
- 2026-01 영상에서 안티그래비티가 만든 main.js 앞부분(화면 원문, 이후는 화면에서 잘림)
/**
* 간단한 채팅 명령어 예제
* Minecraft Bedrock Script API
*/
import { world, system } from "@minecraft/server";
// ===========================
// 방법 1: /scriptevent 명령어 사용 (권장)
// 사용법: /scriptevent cmd:help 또는 /scriptevent cmd:hello
// ===========================
system.afterEvents.scriptEventReceive.subscribe((event) => {
const { id, message, sourceEntity } = event;
// sourceEntity가 플레이어인지 확인
if (!sourceEntity || sourceEntity.typeId !== "minecraft:player") return;
const player = sourceEntity;
// 명령어 처리
switch (id) {
case "cmd:help":
player.sendMessage("§e=== 도움말 ===");
player.sendMessage("§a/scriptevent cmd:help §f- 도움말 표시");
player.sendMessage("§a/scriptevent cmd:hello §f- 인사하기");
player.sendMessage("§a/scriptevent cmd:time §f- 현재 게임 시간");
player.sendMessage("§a/scriptevent cmd:pos §f- 현재 위치 확인");
player.sendMessage("§a/scriptevent cmd:heal §f- 체력 회복");
break;
case "cmd:hello":
world.sendMessage(`§b${player.name}§f님이 인사합니다! 안녕하세요! 👋`);
break;
case "cmd:time":
const timeOfDay = world.getTimeOfDay();
const hours = Math.floor(timeOfDay / 1000);
const minutes = Math.floor((timeOfDay % 1000) / 16.67);
// … 이하 화면에서 잘림
- AI가 참고한 레퍼런스: wiki.bedrock.dev의 Events 문서(화면). 스티브코딩 GitHub 예제 중 breakBlock.js·chatCommand.js는 이때 “Update to latest Script API patterns and fix deprecated code”로 최신 문법으로 고쳐 둠(03:20 화면).
GPTs로 코드 짜기: 아이템 수리 NPC
- 스크립트 API용 GPTs ‘scriptAPI’에 요청 → main.js에 붙여 넣고
/reload→ 시험 → 고칠 점을 다시 요청(네 번 정도) - 고쳐 간 요청: 새 NPC를 정의하지 말고 기존 NPC 중 이름이 repair일 때만 / 대화창이 뜨지 않게 / “한 번 수리하는데 에메랄드 1개가 소비되도록 해. 그리고 수리하는 아이템은 손에 들고 있는 아이템을 수리하도록 해.”
- 결과: 흙(내구도 없음)·최대 내구도 곡괭이 → 안내만 / 에메랄드 부족 → 수리 안 됨 / “수리 완료! (직접 수리, 비용: 에메랄드 1개)”
- GPTs 지침: 스티브코딩 GitHub(scriptAPI)를 참고하되 예전 문법은 최신 공식 문서를 우선, Microsoft 샘플(minecraft-scripting-samples, minecraft-creator)도 참고



첫 채팅 명령어 만들기
- 메시지가 곧 ‘명령어’, 그 아래 줄에 실행할 마인크래프트 명령을 적음 — 줄을 복사하면 여러 명령이 한꺼번에 실행
world.afterEvents.chatSend.subscribe(e => {
const msg = e.message
if (msg == "명령어1") {
e.sender.runCommand("say 명령어1을 실행함")
}
if (msg == "명령어2") {
e.sender.runCommand("say 명령어2를 실행함")
e.sender.runCommand("give @s apple")
}
})
- 결과: 명령어1 → 메시지 / 명령어2 → 사과(
give줄을 두 번 쓰면 2개) / 명령어3 →effect @s speed chatSend는 베타 API — 월드의 실험 기능 ‘베타 API’가 꺼져 있으면 동작하지 않음

교사용 메모 · 채팅 명령어 전체 코드와 예전 문법
- 2023-11 영상 화면의 main.js 전체(Bridge, @minecraft/server 1.7.0 시절)
console.warn("불러옴")
import * as server from "@minecraft/server"
import * as ui from "@minecraft/server-ui"
const world = server.world
// 커스텀 명령어
world.afterEvents.chatSend.subscribe(e => {
const msg = e.message
if (msg == "명령어1") {
e.sender.runCommand("say 명령어1을 실행함")
}
if (msg == "명령어2") {
e.sender.runCommand("say 명령어2를 실행함")
e.sender.runCommand("give @s apple")
}
if (msg == "명령어3") {
e.sender.runCommand("say 명령어3을 실행함")
e.sender.runCommand("effect @s speed")
e.sender.runCommand("")
}
})
- 예전 버전(2022-09 영상 「5분 완성! 여러 커맨드를 한번에 실행하는 나만의 커맨드만들기」):
mojang-minecraft모듈과beforeChat이벤트를 써서 지금은 동작하지 않음. 영상 설명란도 2023 영상의 업데이트된 문법을 보라고 안내함. 당시 실험 기능 이름은 ‘게임테스트 프레임워크’.
import { world } from 'mojang-minecraft'
world.events.beforeChat.subscribe((ev) => {
const player = ev.sender
const msg = ev.message
if (msg == "a") {
ev.cancel = true
player.runCommand("say a를 입력했음")
} else if (msg == "s") {
ev.cancel = true
player.runCommand("say s를 입력했음")
player.runCommand("give @s apple")
} else if (msg == "여기에 명령어 쓰기3") {
ev.cancel = true
player.runCommand("say 실행됨3")
}
})

이벤트 기초: 블록을 부수면 점수
- 채팅
1→scoreboard objectives add diamond dummy 다이아몬드/scoreboard objectives setdisplay sidebar diamond/scoreboard players set @a diamond 0 - 이벤트에서 ‘부순 사람’과 ‘부서진 블록’을 알 수 있음 → 액션바에 표시, 다이아몬드 광석이면 +1
world.beforeEvents.playerBreakBlock.subscribe((event) => {
const playername = event.player.name;
const block = event.block.typeId;
world.getDimension("overworld").runCommandAsync(`title @a actionbar ${playername}가 ${block}를 캤습니다.`);
if (block === "minecraft:diamond_ore" || block === "minecraft:deepslate_diamond_ore") {
world.getDimension("overworld").runCommandAsync(`scoreboard players add ${playername} diamond 1`);
}
});
- 다른 블록도 점수로:
||로 이어 붙이거나 if 묶음을 복사(영상은 잔디 추가) → Ctrl+S,/reload

타이머: system.runInterval
- 채팅
카운트다운 10(붙여 쓰기) → 제목 “10초 카운트다운 시작”, 액션바 “남은 시간: 6초”, 0초에 “시간 종료” /정지→ 멈춤 / 숫자가 아니면 “카운트다운 뒤에는 숫자를 입력해주세요.” - 변수 두 개:
sec(남은 초),countingIs(세는 중인지) — 채팅 이벤트가 값을 바꾸고, 1초마다 도는 함수가 줄이고 보여 줌
// 시간 간격 설정: 20틱마다 실행 (1초에 한 번)
const interval = 20;
// system.runInterval을 사용하여 주기적으로 실행
system.runInterval(printStoredMessage, interval);
- 응용: 시청자가 보내 준 currenttime.js —
system.runInterval로 모든 플레이어 액션바에 지금 한국 시간 표시



UI 기초: 버튼 창 만들기
- 나침반을 들고 오른쪽 클릭(itemUse 이벤트) → ‘순간 이동 장치’ 창: 저장하기(현재 위치) / 이동하기(저장한 곳으로 tp)
const formData = new ActionFormData();
formData.title("순간 이동 장치").body("현재 위치를 저장하거나 저장된 위치로 이동하세요");
formData.button("저장하기");
formData.button("이동하기");
formData.show(player).then((response) => {
if (response.canceled) {
return;
}
// response.selection === 0 → 위치 저장 / === 1 → 이동 (줄임, 전체는 노트)
});
- 버튼 번호
selection: 첫 버튼 0, 둘째 1 / 저장하기 전에 이동하기 → “저장된 장소가 없음”

교사용 메모 · 예제 전체 코드: 블록 이벤트·타이머
- 블록 부수기 예제의 채팅 부분(화면 원문). 이벤트 부분은 위 슬라이드와 같음.
console.warn("불러옴")
import { world, system } from "@minecraft/server";
// 명령어 1로 스코어보드 값 약속하기
world.afterEvents.chatSend.subscribe(e => {
const msg = e.message
if (msg == "1") {
e.sender.runCommand("scoreboard objectives add diamond dummy 다이아몬드")
e.sender.runCommand("scoreboard objectives setdisplay sidebar diamond")
e.sender.runCommand("scoreboard players set @a diamond 0")
}
})
- 타이머 main.js 전체(화면 원문, timer.js)
console.warn("불러옴")
import { world, system } from "@minecraft/server";
// 플레이어 메시지를 저장할 변수
let sec = 0;
let countingIs = false;
// 플레이어가 메시지를 입력할 때마다 호출되는 이벤트 핸들러
world.afterEvents.chatSend.subscribe((event) => {
const player = event.sender;
const message = event.message;
// '카운트다운'이라는 단어가 포함된 경우에만 변수에 저장
if (message.includes('카운트다운')) {
// '카운트다운'이라는 단어를 빼고 저장
const messageToSave = message.replace('카운트다운', '').trim();
// 입력한 메시지가 숫자인지 확인
if (isNaN(messageToSave)) {
player.sendMessage("카운트다운 뒤에는 숫자를 입력해주세요.");
return;
}
sec = Number(messageToSave);
console.log(`${sec}초 카운트다운 시작`);
world.getDimension("overworld").runCommandAsync(`title @a title ${sec}초 카운트다운 시작`);
countingIs = true;
}
// '정지' 입력하면 카운트다운 멈추기
if (message === "정지") {
sec = 0;
console.log(`정지하기`);
countingIs = false;
}
});
// 남은 시간을 출력하는 함수
function printStoredMessage() {
if (countingIs && sec > 0) {
sec--;
world.getDimension("overworld").runCommandAsync(`title @a actionbar 남은 시간: ${sec}초`);
} else if (sec === 0 && countingIs) {
countingIs = false;
world.getDimension("overworld").runCommandAsync(`title @a actionbar 남은 시간: ${sec}초`);
world.getDimension("overworld").runCommandAsync(`title @a title 시간 종료`);
}
}
// 시간 간격 설정: 20틱마다 실행 (1초에 한 번)
const interval = 20;
// system.runInterval을 사용하여 주기적으로 실행
system.runInterval(printStoredMessage, interval);
- 영상(2023-12) 코드의
runCommandAsync는 최신 @minecraft/server에서 지원이 끝나runCommand로 바꿔야 함(아래 ‘스크립트 API 소개 메모’). GitHub의 코드는 최신 문법으로 고친 것이 있으니 GitHub 쪽을 먼저 쓰기.

교사용 메모 · 예제 전체 코드: UI·현재 시간
- 순간 이동 UI main.js 전체(화면 원문, UItp.js)
import { world, system } from "@minecraft/server";
import { ActionFormData } from "@minecraft/server-ui";
const afterEvents = world.afterEvents;
let playerPositionX, playerPositionY, playerPositionZ;
//아이템 사용했을 때 ui열기
afterEvents.itemUse.subscribe((data) => {
const block = data.itemStack
const player = data.source
if (block.typeId == "minecraft:compass") {
showForm(player);
}
});
//ui설정
function showForm(player) {
const formData = new ActionFormData();
formData.title("순간 이동 장치").body("현재 위치를 저장하거나 저장된 위치로 이동하세요");
formData.button("저장하기");
formData.button("이동하기");
formData.show(player).then((response) => {
if (response.canceled) {
return;
}
// 위치 저장하기
if (response.selection === 0) {
playerPositionX = player.location.x
playerPositionY = player.location.y
playerPositionZ = player.location.z
player.runCommandAsync("title @a actionbar 위치 저장 완료");
}
//위치로 이동하기
if (response.selection === 1) {
if (playerPositionX == null) {
player.runCommandAsync("title @a actionbar 저장된 장소가 없음");
} else {
player.runCommandAsync(`tp @s ${playerPositionX} ${playerPositionY} ${playerPositionZ}`);
player.runCommandAsync("title @a actionbar 이동 완료");
}
}
});
}
- 좌표를 코드 맨 위의 변수(
let playerPositionX, …) 하나에 저장하므로 플레이어별로 따로 저장되지 않습니다. 여러 플레이어가 쓰면 마지막에 저장한 사람의 위치로 덮어씁니다. 확장 과제: 버튼을 하나 더 만들어 두 번째 장소 저장. - 현재 시간 표시 currenttime.js 앞부분(화면 원문, 이후는 잘림)
import { world, system } from "@minecraft/server"
//플럼님이 제공한 코드입니다.
system.runInterval(() => {
for (const player of world.getAllPlayers()) {
// 한국 시간 계산
const kr_date = new Date(new Date().getTime() +
(new Date().getTimezoneOffset() * 60 * 1000) +
(9 * 60 * 60 * 1000));
// 요일 배열 (한글)
const weekDays = ['일', '월', '화', '수', '목', '금', '토'];
// 날짜 형식 구성
const year = kr_date.getFullYear();
const month = kr_date.getMonth() + 1; // getMonth()는 0부터 시작
const date = kr_date.getDate();
const day = weekDays[kr_date.getDay()];
const time = kr_date.toString().split(` `)[4];
// 액션바에 표시 (YYYY년 MM월 DD일 (요일) HH:MM:SS)
player.onScreenDisplay.setActionBar(
// … 이하 화면에서 잘림 (currenttime.js 참고)

교사용 메모 · 한 걸음 더: 스크립트 API 예제 7가지 (교안 v07)
- 채팅 명령어: 채팅 입력에 반응
- 블록 캐기 알림: 다이아몬드 점수
- 침대 알람 폼: ActionFormData
- 나침반 순간이동: 위치 저장·이동 폼
- 카운트다운: runInterval, 20틱=1초
- 메시지 저장: 채팅 기록 남기기
- 채팅 퀴즈: 문제 배열 + 정답 비교
- 모듈:
@minecraft/server/@minecraft/server-ui
import { world } from '@minecraft/server';
// 예전: dim.runCommandAsync(...)
world.getDimension('overworld')
.runCommand('say 안녕!');
- AI 활용: “이런 기능을 스크립트로” 요청 / 주의: chatSend는 베타 API 실험 기능 필요 / 교육용: .mcaddon + 정식(stable) API만 쓰는 코드
슬래시(/)로 시작하는 커스텀 명령어
- 2025년 업데이트로 스크립트 API에서
/로 시작하는 나만의 명령어를 등록할 수 있게 됨 — 채팅창에 이름·설명·매개변수 안내가 뜸 - 예제 figureMaker.js(도형 명령어)의 사용 예(코드 주석 원문):
/figure:circle ~ ~ ~ 10 minecraft:diamond_block xz true
/figure:sphere ~ ~ ~ 10 minecraft:diamond_block true
/figure:hemisphere ~ ~ ~ 10 minecraft:diamond_block y true
/figure:cylinder ~ ~ ~ 10 20 minecraft:diamond_block y true
- 원
[center: x y z] [radius: int] [blockType: Block] [direction: string] [fill: Boolean]— 방향 xy·xz·yz, 채우기 true/false - 반지름 100 구는 끝까지 안 만들어짐 → 시뮬레이션 거리를 늘리면 될 것 같다고 함(영상 추측)
- 코드: 서버 시작 이벤트에서
customCommandRegistry로 이름·설명·권한 레벨·매개변수를 등록(노트)


교사용 메모 · 커스텀 명령어 코드 구조
- 서버가 시작될 때(
system.beforeEvents.startup)customCommandRegistry로 선택지(enum)와 명령어를 등록
system.beforeEvents.startup.subscribe(e => {
const command = e.customCommandRegistry;
command.registerEnum(`figure:direction`, [`xy`, `xz`, `yz`]);
command.registerCommand({
name: `figure:circle`,
description: "원 모양을 생성합니다",
permissionLevel: 1,
optionalParameters: [
{ type: 6, name: "center" }, // 중심점 좌표
{ type: 1, name: "radius" }, // 반지름 (정수)
{ type: 7, name: "blockType" }, // 블록 타입
{ type: 9, name: "figure:direction" }, // 방향 (xy, xz, yz 평면)
{ type: 0, name: "fill" } // 내부 채우기 여부
]
}, (playerData, center, radius, blockType, direction, fill) => {
// 입력하지 않은 값은 기본값: direction || "xz", fill || false
system.run(() => { /* 원의 방정식으로 블록 놓기 (줄임) */ });
});
});
- 매개변수 타입: 0 Boolean · 1 Integer · 2 Float · 3 String · 4 EntitySelector · 5 PlayerSelector · 6 Location · 7 BlockType · 8 ItemType · 9 Enum
- 권한 레벨: 0 Any · 1 GameDirectors(운영자·커맨드 블록, 영상 값) · 2 Admin · 3 Host · 4 Owner(콘솔)

코드를 애드온으로, 교육용 에디션에 적용
- 스티브코딩 GitHub(scriptAPI)에서 코드 복사 → Bridge 새 프로젝트(베타 API, 이름 예: testAPI) →
scripts/main.js에 붙여 넣고 Ctrl+S manifest.jsondependencies 버전 확인 → 이것만으로 월드의 행동 팩 목록에 나타남- 파일로 나눠 주려면 ⋮(More…) → Export As →
.mcaddon(.brproject는 Bridge에서 다시 여는 프로젝트 파일) - 교육용: .mcaddon을 오른쪽 클릭 → 연결 프로그램 → Minecraft Education
- 교육용 월드 설정에는 실험 기능 메뉴가 없음 → chatSend 같은 베타 전용 API는 공식 문서상 정식(stable) 채널에 없고(2026-10 공식 문서 기준), 교육용 에디션은 베타 버전 종속성을 넣어도 불러오지 않았습니다(2026-07 실측). 교육용 수업에는 베타가 필요 없는 정식 API만 쓰는 코드를 고르기
- 버전마다 달라지므로 수업 전에 교사 PC에서 먼저 시험


서버에 애드온 적용하기
- 행동 팩을 서버 폴더의
development_behavior_packs에 복사 - 팩
manifest.json의 headeruuid= 월드 폴더world_behavior_packs.json의pack_id— 팩을 더 넣을 땐 항목을 하나 더 만들기 server.properties의 월드 이름을 새 월드로 → 실행, 콘솔에Pack Stack줄이 나오면 성공
- 고칠 때는 콘솔에
stop후 수정 / 치트는allow-cheats=false→true로 바꾸고 재시작


교사용 메모 · 애드온·서버 메모
- 코드→애드온 영상(2025-01)의 manifest 값: server
1.17.0-beta(화면), server-ui 1.4(자막). Bridge의 대상 버전은 쓰는 교육용 에디션의 게임 버전 이하로 낮춰서 만들기. 영상 설명란이 안내한 ‘교육용 에디션에서 실험기능 켜기’ 튜토리얼은 교육용 에디션에 애드온이 적용안된다면 이렇게 하면 됩니다(2023)로, UI Upgrade 애드온을 글로벌 리소스로 켜서 실험 기능 메뉴를 보이게 하는 방법입니다. 2026-07 실측에서는 교육용 에디션이 베타 API를 불러오지 않았으므로 이 방법에 기대지 말고 정식(stable) API만 쓰세요. - 서버용 월드를 게임에서 먼저 만드는 까닭: 월드를 만들 때 정한 설정(베타 API, 행동 팩)이 그대로 서버로 옮겨집니다. 콘솔에
Level Name: apiworld가 나오면 월드 이름이 바뀐 것. - 운영 중에는 행동 팩을 고칠 수 없습니다. 팩을 더 넣을 때 폴더 복사만으로는 안 불러오므로, 그 팩 manifest의 header uuid를 복사해
world_behavior_packs.json에 항목을 하나 더 만들고pack_id에 넣습니다.
[
{
"pack_id" : "37ecd9df-cd63-4bdd-ba49-fd4def5ca511",
"version" : [ 1, 0, 0 ]
}
]
- 서버에서는 게임 안에서 치트를 켤 수 없어
server.properties의allow-cheats를true로 바꿉니다. - 서버 폴더의
bedrock_server_how_to.html: server.properties·허용 목록(allowlist)·권한(permissions)·운영 명령·백업 설명. 서버 설치·운영은 ‘스크립트 API 서버 운영’, ‘전용 서버’ 페이지.


웹소켓으로 게임과 외부 프로그램 연결하기
- 서버 준비 (교사 PC):
npm install ws uuid/ F5 로 서버 실행 → “준비 완료” - 게임 채팅에서 연결 · 종료:
/connect localhost:<포트>//connect stop— 영상 예제는/connect localhost:3000
- 안 될 때: 관리자 명령 프롬프트에서 루프백 허용 명령 실행(노트 참고)
- 자동 번역: hi → 안녕 / 영어 채팅을 한국어로 (show me the money → 돈을 보여줘, 한국어는 그대로)
- AI 챗봇:
!AI 메시지/ 로컬 Ollama가 답변 —!ai 니가 인공지능이니?→ “네, 저는 구글에서 훈련된 대규모 언어 모델입니다.” - 코드: github.com/ssakspirit/websocket



웹소켓 기본 예제: 채팅을 콘솔로 받기
- Node.js 설치 → VS Code에서 폴더 열기 →
mineserver1.js에 설명란 코드 붙여 넣기 → 터미널npm install ws uuid→ 실행 및 디버그(F5)
// 3000번 포트에 새로운 웹소켓 서버 생성
console.log('준비 완료. Minecraft 채팅에서 /connect localhost:3000을 입력하세요')
const wss = new WebSocket.Server({ port: 3000 })
wss.on('connection', socket => {
console.log('연결됨')
socket.on('message', message => {
const parsedMessage = JSON.parse(message.toString()); // 메시지를 JSON으로 파싱
console.log('받은 메시지:', parsedMessage.body.message); // 실제 메시지 출력
})
})
- 화면 코드의 일부(try/catch·연결 종료 처리는 줄임, 앞의 모듈 불러오기 줄은 화면에 없음 — 설명란 코드 확인)
- 게임: “ws://localhost:3000 서버에 연결되었습니다” → 채팅 ‘들리니?’가 디버그 콘솔에 ‘받은 메시지: 들리니?’


웹소켓이 안 될 때
- 설정 → 일반 → 네트워크 설정: ‘웹 소켓 활성화됨’ 켜기, ‘암호화된 Websocket이 필요합니다’ 끄기
- 암호화를 켜면 교육용 클래스룸 모드와 대부분의 웹소켓 서비스(코드작성기 등)가 작동하지 않음
- 베드락은 게임 중에도 바꿀 수 있음 / 교육용은 게임 안에서 안 바뀜, 첫 화면에서도 안 바뀌면 → 프로그램을 종료하고 다시 실행해서 설정 → 일반에서 바꾸기
- 그래도 연결이 안 되면 관리자 권한 명령 프롬프트에서 루프백 허용(베드락, ‘성공’이 뜨면 됨):
CheckNetIsolation LoopbackExempt -a -n="Microsoft.MinecraftUWP_8wekyb3d8bbwe"


교사용 메모 · 웹소켓 준비 메모
- 웹소켓: 게임 채팅과 내 컴퓨터의 프로그램(Node.js 서버)이 실시간으로 메시지를 주고받는 통로입니다.
- 준비: Node.js, VS Code, (챗봇을 쓸 때만) Ollama와 로컬 모델(예: llama2, mistral, gemma — 수 GB 필요). 영상의 AI 프로그램은 디스코드 안내에 ‘추가 설치: ollama.com/download/windows’, 배포 파일 WebSocket Gemma2.zip(화면).
- 서버 주소의 포트 번호는 서버 코드에 적힌 값을 씁니다(예제 코드 확인). 영상 예제는 3000번(
new WebSocket.Server({ port: 3000 })). - 연결이 안 되면 관리자 명령 프롬프트에서 루프백 허용:
CheckNetIsolation LoopbackExempt -a -n="Microsoft.MinecraftUWP_8wekyb3d8bbwe"(영상 확인(1:59)) - → 노션 원문의 패키지 이름은 베드락(MinecraftUWP) 기준입니다. Microsoft Store로 설치한 교육용 에디션의 패키지 이름은
Microsoft.MinecraftEducationEdition_8wekyb3d8bbwe입니다(교사 PC의 교육용 에디션 데이터 폴더 이름으로 확인). 교육용 에디션은 ‘암호화된 웹소켓’도 꺼야 합니다(아래 「이 설정 반드시 하세요」 영상). - 번역·AI 프로그램(영상): 웹소켓 연구 디스코드에서 받은 프로그램을 실행하면 웹소켓이 열리고
/connect localhost:3000으로 연결합니다. 번역은 Minecraft Translate, AI는 Minecraft Chat AI(Ollama 추가 설치 → 셋업 → 스타트, 채팅!ai {메시지}). AI 답은 느리고 긴 답은 여러 줄로 나뉩니다. - Ollama 챗봇은 로컬 모델이라 대화 내용이 외부로 나가지 않습니다. 교실 시연은 교사 PC 한 대로 충분합니다.
- 기본 예제 화면 원문(4~25줄):
// 3000번 포트에 새로운 웹소켓 서버 생성
console.log('준비 완료. Minecraft 채팅에서 /connect localhost:3000을 입력하세요')
const wss = new WebSocket.Server({ port: 3000 })
// Minecraft에서 "/connect localhost:3000"을 입력하면 연결이 생성됩니다
wss.on('connection', socket => {
console.log('연결됨')
// 클라이언트로부터 메시지를 받았을 때 처리
socket.on('message', message => {
try {
const parsedMessage = JSON.parse(message.toString()); // 메시지를 JSON으로 파싱
console.log('받은 메시지:', parsedMessage.body.message); // 실제 메시지 출력
// 여기에 메시지 처리 로직을 추가할 수 있습니다
} catch (error) {
console.error('메시지 처리 중 오류 발생:', error); // 오류 처리
}
})
// 연결이 종료되었을 때 처리
socket.on('close', () => {
console.log('연결 종료됨')
베드락에서 쓰는 코드작성기
- 스티브코딩이 만든 베드락 코드빌더: 메이크코드처럼 블록을 끼워 에이전트·명령을 실행(웹소켓으로 연결, 자바 에디션은 지원 안 함)
- GitHub codebuilderBedrock-release 최신 릴리즈에서 셋업 파일·실행 파일 받기(다운로드가 막히면 ‘유지’)
- setup.bat → 오른쪽 클릭 ‘관리자 권한으로 실행’ (한 번만)
- 실행 파일 실행 → 허용 → 관리 페이지
localhost:4000/admin, 블록 코딩 페이지localhost:4000 - 마인크래프트 채팅창(T)에 Ctrl+V(
/connect localhost:3000, 이미 복사됨) → 엔터 - 안 되면: 네트워크 설정 버튼(최초 1회) → 설정 → 일반에서 WebSockets 활성화 켜기·암호화된 WebSockets 끄기

코드작성기 예제 불러와 실행하기
- 저장 → XML 파일, 불러오기 → 시작 버튼 없이 바로 실행
- 예제 채팅 명령: 1 비 / 2 밤 / 3 화면 제목 / 4 경험치 100 / 5 유리 채우기 / 7 텔레포트 / 8 소 제거, 함수 블록도 있음
- 점수 예제: 블록을 부수면 +1, 채팅
점수→ 현재 점수 / 에이전트 예제:계단→ 에이전트가 계단을 지음 - 메이크코드 명령 블록의 6~70% 구현 + 순정에 없는 이벤트(플레이어가 죽으면, 슬라임 블록에서 튀어오르면, 화살이 과녁을 맞히면, 장비 착용)
- 블록에 마우스를 올리면 설명, 오른쪽 클릭 → ‘도움말 보기’


교사용 메모 · 코드작성기 개발 과정과 메모
| 편 | 새로 생긴 것 |
| 1편 (2025-05) | BedrockAgent.exe + setup.bat, 채팅 명령 1~6: 에이전트 TP·블록 놓기·밭 만들기(6번 반복)·setblock·fill(속 비우기) |
| 2편 (2025-09) | 시작 페이지·네트워크 설정, 몹·모양 범주, 블록 설치·파괴 이벤트, 카메라 상대 위치 블록 탐지, 아이템 획득, XML 저장, 다른 플레이어도 채팅 명령 실행 |
| 3편 (2026-08) | GitHub 릴리즈 배포, 메이크코드 블록 6~70%, 에이전트 다시 사용, 도움말, 추가 이벤트 |


- 1편(2025-05): 실행하면 아무 창이 안 보여도 실행된 것. 콘솔 안내 “1. 마인크래프트 채팅창을 엽니다 (T키) 2. 아래 명령어를 붙여넣기 하세요 (Ctrl+V) /connect localhost:3000 (이미 클립보드에 복사되어 있습니다) 3. 엔터키를 눌러 실행하세요 / 연결에 실패할 경우: "setup.bat"를 실행하세요, 마인크래프트가 최신 버전인지 확인하세요”. 블록 페이지가 자동으로 안 열리면 http://localhost:4000 에 접속.
- 1편 fill 예: 시작 좌표 ~1 ~1 ~1, 끝 좌표 ~10 ~10 ~10, 금 블록, 채우기 옵션으로 속 비우기(영상에서 위치 입력 버그를 말함).
- 2편(2025-09): 반구는 채팅 1(모양 범주), 잔디블록 설치·파괴 시 “잔디블록을 설치했습니다./캤습니다.”, 채팅 2 → 카메라 상대 위치 오른쪽 0·위 0·앞 1에 잔디가 있으면 알려 줌, 나무 검을 주우면 ‘나무검 획득’. 다른 플레이어가 명령을 친 결과는 영상 02:49 화면에서 확인(누구 위치 기준인지는 두 명이 함께 시험해 보며 학생과 찾아보기 좋은 질문).
- 3편 연결 문제 점검 순서(설명란): ① 암호화된 웹소켓이 꺼져 있는지(가장 흔한 원인) ② 웹소켓이 켜져 있는지 ③ setup.bat을 관리자 권한으로 실행했는지 ④ 베드락 또는 에듀케이션 에디션인지.
- 준비물(GitHub README): Windows 10 또는 11(64비트), 마인크래프트 베드락 에디션, 크롬 또는 엣지 브라우저. 교육용 에디션에서 쓸 수 있다는 설명란 안내가 있으니, 교실 PC에서 미리 시험해 보세요.


교사용 메모 · 스크립트 API 소개 메모
- 코드작성기(MakeCode)보다 한 단계 깊은 방법입니다. 행동 팩에 JavaScript 파일을 넣어 게임 규칙 자체를 바꿉니다.
- 초등 교사 연수에서는 깊게 다루지 않고 “AI에게 이런 스크립트를 요청할 수 있다” 정도로 소개합니다.
- 노션 예제(2023)는 runCommandAsync를 쓰는데, 최신 @minecraft/server에서는 지원이 끝나 runCommand로 바꿔야 합니다.
- chatSend(채팅 이벤트)는 베타 API 실험 기능을 켜야 동작합니다(영상 확인(1:27): 채팅 명령어 예제에서 베타 API를 켬).
- 교육용 에디션: Bridge에서 .mcaddon으로 내보내 교육용 에디션으로 열면 행동 팩은 적용되지만, 실험 기능(베타 API) 메뉴가 없어 그 메뉴를 나오게 하는 애드온이 따로 필요합니다 — 영상 확인(5:54, 4:09). 버전마다 달라질 수 있어 연수 전에 확인하세요.
- 타이머 예제는 system.runInterval(…, 20) = 1초(20틱 = 1초).
- AI에게 코드를 받을 때(2025~2026 영상): ChatGPT는 기초 설명과 “스크립트 API를 쓰겠다”는 말을 먼저 주면 코드를 대략 짜 주지만 옛 문법을 자주 추천하므로 공식 문서와 함께 확인합니다. 복잡한 기능일수록 정확한 프롬프트와 코드를 읽는 힘이 필요합니다.
스크립트 API 튜토리얼 시리즈 한눈에
- 채널 ‘스크립트API’ 영상 61편 · 코드는 GitHub에서 복사해 main.js에
| 분류 | 대표 영상 | 쓰임 |
| 시작하기 | 개발 환경(Bridge + AI 편집기), 채팅 명령어, 코드 → 애드온 | 첫 1~2편 |
| 아이템·스킬 | 커스텀 인챈트 18가지, 스킬 아이템, 강화, 귀환서 | 게임 보상 |
| 경제·상점 | 에메랄드 은행(이자), 송금, UI 상점, 보상 쿠폰 | 경제 교육 |
| 서버·공동체 | 길드, 칭호, 팀 채팅, 도배 금지, 입장 메시지 | 학급 서버 |
| 구역·보안 | 보호 구역, 허용·거부 구역, 열쇠로 잠그는 상자 | 건축물 보호 |
| 게임 시스템 | 퀘스트, 퀴즈(멀티), PvP 킬 기록·부활, 팀킬 금지 | 미니게임 |

교사용 메모 · 스크립트 API 시리즈 메모
- 스티브코딩 채널의 스크립트 API 영상(61편)을 쓰임새별로 묶은 표입니다. 대부분 1~5분 길이이고, 설명란의 GitHub 코드를 main.js에 그대로 붙여 넣어 쓰는 방식입니다.
- 시작 순서(영상 확인): Bridge에서 새 프로젝트를 만들 때 베타 API를 켬 → main.js에 코드 → 월드의 실험 기능에서 ‘베타 API’를 켜고 행동 팩 적용 → 오류는 설정의 제작자 로그로 확인, manifest.json의 @minecraft/server 버전을 로그에 나온 버전으로 맞춤 → 코드를 고친 뒤에는 /reload(5:34).
- 교육용 에디션(영상 확인, 5:54): Bridge에서 .mcaddon으로 내보내 교육용 에디션으로 열면 팩은 적용되지만, 실험 기능(베타 API) 메뉴가 없어 그 메뉴를 나오게 하는 애드온이 따로 필요합니다. 버전마다 달라질 수 있어 연수 전에 확인하세요.
- 2026년 영상(jU1PpoG-VV8)부터는 코드 편집을 AI 편집기(구글 안티그래비티)에 맡깁니다. 공식 문서 주소를 레퍼런스로 함께 주면 오류가 줄어듭니다.
- 영상 날짜(시작하기 묶음): 2023-11 채팅 명령어·개발 환경, 2023-12 블록 이벤트·타이머, 2024-01 UI, 2025-01 코드→애드온, 2025-05 커스텀 명령어, 2025-10 GPTs, 2026-01 AI 편집기. 옛 영상은 API 버전이 달라 manifest 버전을 바꿔야 할 수 있습니다(그 밖에 확인된 것: 2025-02 보호 구역·은행·커스텀 인챈트 18가지, 2026-01 좀비 소환).
- PART 08 「스크립트 API 예제 7가지」와 함께 보면 좋습니다.
수업 팁
- 연수 전에 교사 PC에서 Bridge → 월드 설정 → 콘텐츠 로그 →
/reload한 바퀴를 먼저 돌려 보기 - 가장 흔한 오류는 manifest 버전 — 로그를 읽고 고치는 과정을 그대로 디버깅 학습 소재로
- 첫 수업은 채팅 명령어 3개 만들기 → 학생마다 나만의 명령어(아이템·효과·메시지)를 만들어 친구와 바꿔 써 보기
- AI에게는 레퍼런스 주소를 함께 주고, 한 번에 다 요구하지 말고 결과를 보며 고쳐 요청하기(수리 NPC는 네 번)
- 웹소켓·코드작성기는 학교망·관리자 권한이 걸림돌 → 수업 전 연결 시험, ‘웹소켓 켜기·암호화 끄기’를 점검표에
더 보기
- 스크립트 API 서버 운영: 길드·칭호·팀 채팅·도배 금지·입장 메시지·보호 구역 등 학급 서버를 꾸리는 스크립트
- 스크립트 API 상점·경제: 에메랄드 은행(이자)·송금·UI 상점·보상 쿠폰으로 하는 경제 교육
- 스크립트 API 아이템·인챈트: 커스텀 인챈트·스킬 아이템·강화·귀환서처럼 특별한 능력을 가진 아이템
- 스크립트 API PvP·몹: PvP 킬 기록·묘비 부활·팀킬 금지·몹 보상 같은 전투와 몹 시스템
- 애드온 만들기: 스크립트 API 없이 JSON과 Bridge로 만드는 아이템·블록·엔티티 애드온