Pyxen Script

Pyxen 게임은 게임을 위해 만든 Python 방언인 Pyxen Script로 작성합니다. 들여쓰기, def, 리스트, 딕셔너리, f-문자열, 컴프리헨션까지 Python의 문법과 느낌을 그대로 갖추고 있습니다. 달라지는 것은 그 아래입니다. 코드는 프로젝트 전체가 한꺼번에 검사되고 게임이 시작되기 전에 컴파일되며, 단 하나의 일을 위해 만든 런타임에서 실행됩니다. 바로 모든 기기에서 게임을 똑같이 실행하는 일입니다.

Python을 이미 알고 있다면 작성하는 코드 대부분이 예상대로 동작합니다. 이 페이지에서는 Pyxen Script가 왜 있는지, Python과 무엇을 공유하는지, 그리고 무엇을 의도적으로 뺐는지 설명합니다.

왜 방언인가

게임이 언어에 요구하는 것은 스크립트가 요구하는 것과 다릅니다.

이전 버전의 Pyxen은 MicroPython 인터프리터를 사용했으며, Pyxen Script가 이를 대체합니다.

Python과 같은 점

Pyxen Script는 수백 개의 한 줄짜리 Python 관용구로 테스트되며, 각각 표준 Python의 출력과 비교됩니다. 다음은 모두 Python과 똑같이 동작합니다.

다른 점

클래스가 없습니다

Pyxen Script에는 class가 없습니다. 의도된 설계입니다.

Pyxen 게임에서 상태는 엔티티와 그 컴포넌트에 있습니다. 엔진이 이들을 소유하고, 촘촘하게 저장하며, 프레임 인스펙터에서 보여 줍니다. 클래스는 같은 상태를 두는 두 번째 장소가 되며, 엔진에도 인스펙터에도 보이지 않습니다. 그래서 Python 코드라면 클래스를 정의할 곳에서, Pyxen 코드는 엔티티를 생성하고 컴포넌트를 붙인 다음 그것을 다루는 함수를 작성합니다.

전형적인 Python 클래스:

class Enemy:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.hp = 3

    def hit(self):
        self.hp -= 1

같은 내용을 Pyxen Script로:

def spawn_enemy(x, y):
    e = world.spawn(name="enemy", x=x, y=y, sprite=Sprite("slime"))
    e.enemy = {"hp": 3, "speed": 1.5}
    return e

def hit(e):
    e.enemy.hp -= 1
    if e.enemy.hp <= 0:
        world.destroy(e)

def update():
    for e in world.all("enemy"):
        e.x -= e.enemy.speed

엔티티는 이미 위치, 스프라이트, 씬 안의 자리를 갖고 있습니다. enemy 컴포넌트에는 적에게만 해당하는 것을 담고, world.all("enemy")로 모든 적을 찾을 수 있으므로 따로 동기화해야 할 인스턴스 리스트가 없습니다. 최고 점수 표나 레벨 설명처럼 게임 오브젝트가 아닌 단순한 데이터에는 딕셔너리와 리스트를 쓰세요. 전체 모델은 엔티티 및 컴포넌트를 참고하세요.

예외가 없습니다

Pyxen Script에는 try, except, finally, raise가 없습니다. 이것 역시 의도된 설계입니다.

Pyxen Script의 오류는 게임을 멈추고, 그곳까지 이어진 호출과 함께 해당 줄에서 보고됩니다. 중간에 잡아챌 수 있는 것이 없으므로, 오류가 except: pass에 삼켜져 세 레벨 뒤에 조용히 이상하게 동작하는 게임이 되는 일은 없습니다.

게임 코드의 try 블록 대부분은 직접 답할 수 있는 질문을 던집니다. 그 질문을 직접 쓰세요.

# 이 엔티티에 컴포넌트가 있는가?
hp = e.health.value if e.has("health") else 0

# 이 키가 딕셔너리에 있는가?
best = scores.get(name, 0)

# 이 텍스트가 숫자인가?
if text.isdigit():
    level = int(text)

# 이 인덱스가 리스트 범위 안에 있는가?
if i < len(items):
    item = items[i]

assert는 쓸 수 있으며, 조건이 거짓이면 해당 줄에서 게임을 멈춥니다.

그 밖에 Pyxen Script에 없는 것

이 항목들은 모두 게임이 시작되기 전에 이름과 해당 줄로 보고됩니다.

모듈과 import

프로젝트는 하나의 프로그램으로 컴파일됩니다. 그 안의 각 스크립트는 파일 이름으로 이미 서로에게 보입니다. monsters.py에 있는 함수 spawn()은 다른 어떤 스크립트에서든 import 없이 monsters.spawn()으로 호출합니다. 엔진 API(world, input, Sprite 등)도 항상 쓸 수 있습니다.

from pyxen import *나 import monsters처럼 이미 작성해 둔 import는 그대로 동작합니다. Pyxen Script는 이를 불필요한 것으로 취급하므로 지워도 됩니다.