← 작품으로
코드로 세상을 지배하는 마법사3화

코드로 세상을 지배하는 마법사

코드로 세상을 지배하는 마법사

AD
스폰서 광고

3화: 쿨타임 무시

실험장은 관측탑 북쪽의 바위 협곡을 향해 열려 있었다.

안개 속에는 석제 표적 열 개가 줄지어 서 있었다. 표적마다 은가루로 그린 고정 룬이 박혀 있었다. 엘리언은 그 앞에 5서클 화염구 도식을 펼쳐 놓고 마지막 고리를 짚었다.

“정말 이걸 여기서 하실 겁니까?”

레온은 도식과 협곡을 번갈아 보았다.

“5서클이면 탑의 외벽도 녹일 수 있습니다. 표적 열 개로 막을 수 있는 주문이 아닙니다.”

“그래서 사람 없는 방향을 골랐다.”

엘리언은 실험장 뒤쪽의 결계석을 확인했다. 열두 개의 석에 마력을 가득 채워 둔 상태였다. 평소라면 견습생 두 명이 관리해도 충분한 방어 장치였지만 오늘은 달랐다.

그는 손등의 붕대를 풀었다. 어제 벌어진 상처가 아직 붉게 부어 있었다.

“그리고 한 발만 쏘는 실험도 아니다.”

레온의 얼굴이 굳었다.

“몇 발입니까?”

“백 발.”

“백 발을 한 번에요?”

“한 번의 호출로 백 번 실행하는 거다.”

엘리언은 도식에 마력을 흘렸다. 화염구를 뜻하는 붉은 룬과 목표를 지정하는 검은 룬이 실행 고리 안에서 낯익은 문자로 갈라졌다.

cast(fireball, target);

화염구를 목표에 실행한다.

이 문장을 그대로 되풀이하면 대상이 하나의 표식으로 고정되지 않은 채 주문이 겹칠 수 있었다. 열 개의 표적을 세워 둔 이유였다.

“저 고정 룬을 순서표로 묶는다. 발사할 때마다 다음 표적을 가리키게 만들 거야.”

레온은 은가루 주머니를 들고 표적 사이를 뛰어다녔다. 엘리언은 그가 그린 선을 확인한 뒤 도식 안쪽에 새로운 고리를 덧댔다.

for (i = 0; i < 100; i++) {

그 아래에 원래의 호출문을 넣었다.

cast(fireball, target[i]);

}

완성된 것처럼 보였지만 엘리언은 손을 떼지 않았다. 고리의 증가식이 검은 안개에 가려져 있었다.

i = i

“횟수는 세지만 숫자가 변하지 않는다. 이대로 실행하면 첫 번째 순서만 계속 부르게 돼.”

“그럼 백 발이 한 표적에 전부 꽂히는 겁니까?”

“그보다 나쁘다. 첫 번째 화염구가 생긴 자리 위에 다음 화염구가 겹친다.”

레온이 손을 들었다.

“실험을 중단하시는 게 좋겠습니다.”

“중단할 이유는 아직 없다.”

엘리언은 마력선을 검은 안개 앞으로 밀어 넣었다. 선이 튕겨 나가며 손등을 태운 순간 실험장 바닥의 도식이 제멋대로 빛났다.

“대마법사님!”

붉은 불꽃 하나가 발치에서 솟았다. 엘리언이 몸을 비틀어 피하자 두 번째 불꽃이 바로 그 위에서 생겨났다. 세 번째는 어깨 높이에서 피어났다.

조건문이 시작 신호만 읽고 실행 고리를 밀어붙이고 있었다.

“결계 개방!”

레온이 외쳤다. 견습생들이 결계석의 손잡이를 돌리자 푸른 막이 실험장 가장자리를 덮었다. 화염구 세 개가 동시에 막에 부딪혔다. 폭발음이 겹치며 바닥이 흔들렸다.

엘리언은 불꽃 사이를 걸었다. 화염구의 궤적은 모두 하나의 점으로 모이고 있었다.

target[0]

고정 룬은 연결됐지만 순번이 바뀌지 않았다.

“레온. 첫 번째 표적의 룬을 지우지 마라.”

“지금 그게 중요한가요?”

“가장 중요하다.”

엘리언은 목표를 가리키는 선에 표적의 순번을 연결했다.

target[i % 10]

그리고 검은 안개에 가려진 증가식에 짧은 선을 찔러 넣었다.

i++

이번에는 문자가 선명해졌다.

화염구 네 개가 서로 다른 방향으로 튕겨 나갔다. 첫 번째는 1번 표적에 꽂혔고 두 번째는 2번 표적의 옆을 스쳤다. 나머지는 협곡 위 허공에서 터졌다.

“멈추십시오! 이제 방향은 잡혔지만 결계가 버티지 못합니다!”

엘리언은 시야 한쪽의 숫자를 보았다.

i = 4

아직 네 번 실행됐을 뿐인데 실험장 중앙의 마력량은 크게 줄어 있었다. 한 발을 쏘는 힘과 도식을 고치는 힘이 동시에 빠져나가고 있었다.

그는 반복문의 목표 고리를 협곡 안쪽 빈 바위벽으로 연결했다. 열 개의 표적을 차례로 찾는 대신 하나의 대상을 고정하는 구조였다.

“결계를 바깥쪽으로 열어라.”

“그러면 화염구가 협곡으로 빠져나갑니다.”

“그게 목적이다.”

결계의 북쪽 일부가 열렸다.

다섯 번째 화염구가 바위벽을 때렸다. 여섯 번째가 그 옆을 갈랐다. 일곱 번째부터는 일정한 간격으로 날아갔다.

엘리언은 문장이 무엇을 하는지 깨달았다. 주문의 시전 시간이 사라진 것이 아니었다. 실행과 실행 사이에 필요했던 대기 명령을 반복문이 건너뛰고 있었다.

마법사는 한 번 주문을 부른 뒤 다음 호출을 위해 마력을 모아야 한다. 그 짧은 공백이 이 세계에서 말하는 쿨타임이었다.

반복문은 그 공백을 기다리지 않았다.

화염구가 연달아 날아갔다. 바위벽이 붉게 달아오르고 돌가루가 안개처럼 일었다.

“열다섯! 열여섯!”

레온이 기록석을 보며 숫자를 외쳤다.

엘리언은 화염구의 속도보다 마력의 흐름을 살폈다. 정상적인 5서클 주문보다 소모가 컸다. 호출문을 매번 새로 해석하고 대상을 확인하는 데 추가 연산이 필요했다.

마력이 바닥나기 전에 구조를 줄여야 했다.

그는 목표 배열을 단일 표식으로 접었다.

cast(fireball, ravine_wall);

문장이 짧아지자 화염구의 간격이 좁아졌다.

“스물넷!”

바위벽이 크게 흔들렸다. 레온은 더 이상 반박하지 않고 기록석을 움켜쥐었다.

그러나 결계석 하나가 금이 갔다.

푸른 막의 일부가 꺼지며 화염구 세 개가 실험장 안으로 휘었다. 하나는 빈 훈련용 탑을 향했고 둘은 견습생들이 있는 쪽으로 날아갔다.

레온이 몸을 던져 견습생 앞을 막았다.

엘리언은 반복문을 끊지 않았다. 대신 화염구의 목표값을 바꿨다.

target = empty_sky;

세 개의 화염구가 동시에 고개를 틀었다. 불꽃은 레온의 어깨 위를 지나 하늘에서 터졌다.

“저런 것도 문장 하나로 바꿀 수 있습니까?”

“완성된 문장이라면.”

시야의 숫자가 올라갔다.

i = 63

엘리언은 마력의 주 흐름을 둘로 쪼갰다. 한 줄기는 화염구에 남기고 다른 줄기는 결계석으로 돌렸다. 반복문은 실행되면서도 저장고를 한 번에 긁어 가지 못했다.

마력선이 손목을 타고 올라왔다. 살이 타는 냄새가 났다.

“대마법사님. 손이…”

“숫자를 세.”

레온은 입술을 깨물고 기록석을 들었다.

“일흔둘! 일흔셋!”

화염구는 쉼 없이 날아갔다. 바위벽에는 붉은 구멍이 벌집처럼 뚫렸다. 엘리언의 손짓은 한 번뿐이었고 주문의 영창도 없었다.

그는 99라는 숫자가 떠오르는 순간 흐름의 일부를 닫았다.

100번째 호출이 시작됐다.

마지막 화염구는 앞선 것들보다 작았다. 남은 마력을 계산해 만든 한 발이었다. 화염구는 협곡 끝의 바위벽에 닿아 거대한 불꽃의 고리를 만들었다.

i = 100

반복문이 멈췄다.

실험장에 정적이 내려앉았다.

레온은 기록석을 확인했다. 기록된 숫자는 정확히 100이었다.

엘리언은 마력 고리를 거두었다. 무릎이 흔들렸지만 넘어지지는 않았다. 손등의 화상은 붕대 밖으로 번져 있었다.

“성공한 겁니까?”

“반복 실행은 성공했다.”

“그럼 대단한 성공 아닙니까?”

엘리언은 붉게 달아오른 협곡을 바라봤다.

“효율은 실패다.”

그는 도식 가장자리에 남은 마력 찌꺼기를 가리켰다. 5서클 화염구 한 발을 평범하게 쏘는 것보다 백 발을 반복 실행한 비용이 훨씬 컸다.

“우회로가 버티지 않았다면 탑의 결계가 먼저 꺼졌을 거다. 다음에는 반복문 안에서 매번 확인하는 부분을 줄인다.”

레온은 기록석에 화염구의 횟수와 결계석의 손상 정도를 적었다.

그때 하늘이 울렸다.

천둥과 비슷했지만 소리는 너무 얇고 길었다. 실험장 위의 공기가 한 줄로 갈라졌다. 낮인데도 별빛이 틈 사이로 비쳤다.

검은 균열이었다.

지난밤 관측 수정 너머에서 보았던 선보다 가까웠다. 균열의 가장자리에서 붉은 문자들이 빗방울처럼 떨어졌다.

[Warning: unstable loop]

레온은 그것을 보지 못했다. 그는 하늘의 검은 선만 가리켰다.

“저게 또 나타났습니다. 봉인해야 합니까?”

“잠깐.”

엘리언은 시야를 실험장으로 내렸다. 바닥의 화염구 도식 위에는 정상적으로 닫힌 반복문이 떠 있었다.

그런데 바깥에 다른 선이 하나 붙어 있었다.

i = 0

아무도 적지 않은 문장이었다. 100에 도달한 숫자를 다시 0으로 되돌리는 초기화 명령이었다.

엘리언은 마력선을 뻗었다. 반복문이 다시 열리며 협곡 쪽에서 꺼졌던 불씨가 하나씩 살아났다.

“물러서!”

레온이 견습생들을 끌어당겼다.

엘리언은 외부에서 붙은 선을 잡아당겼다. 선은 손가락을 감고 뒤로 끌었다. 붉은 경고가 시야를 가득 메웠다.

[Warning: permission denied]

손등의 상처가 다시 벌어졌다. 엘리언은 이를 악물고 선을 끊으려 했지만 잘리지 않았다. 자신의 문장이 아니었다. 수정할 수 없는 권한 바깥에서 들어온 고리였다.

“결계석을 모두 닫아라. 북쪽 통로를 비워.”

“저건 마법입니까?”

“아직 모른다.”

엘리언은 무작정 고리를 지우지 않았다. 그렇게 하면 100발의 화염구가 동시에 실행될 수 있었다. 그는 먼저 종료 조건을 붙잡았다.

i < 100

조건은 멀쩡했다. 외부의 초기화 명령이 틈을 만들고 있을 뿐이었다.

엘리언은 화염구 호출문과 반복 고리 사이에 임시 봉인선을 그었다. 실행과 초기화 사이를 막는 얇은 문이었다. 불씨가 다시 솟으려다 하나씩 꺼졌다.

마지막으로 검은 선이 실험장 바닥에서 떨어져 나갔다.

하늘의 균열도 천천히 닫혔다. 붉은 문자 하나가 허공에 남았다.

[Warning: permission denied]

오늘 그는 100발의 화염구를 한 번의 호출로 쏘았다. 마법의 대기 시간을 무시했고 주문을 반복하는 구조도 손에 넣었다.

하지만 누군가는 그 구조 바깥에서 숫자를 되돌릴 수 있었다.

자신보다 높은 권한을 가진 무언가가 분명히 존재했다.

레온이 조심스럽게 다가왔다.

“다음 실험은 무엇입니까?”

엘리언은 손등의 붕대를 다시 감았다. 시선은 검은 균열이 사라진 방향에 머물렀다.

“화염구를 더 많이 만드는 실험은 끝났다.”

“그럼요?”

“이제 고장 난 문장이 어디서 들어왔는지 찾는다.”

엘리언은 바닥에 남은 불완전한 고리를 기록지에 옮겼다.

이번에는 세계 전체를 보려 하지 않았다.

오류를 만든 한 줄부터 찾을 생각이었다.

AD
스폰서 광고
YOU MAY ALSO LIKE

이런 작품은 어때요?