Công nghệ cho phép lập trình bên trong một trò chơi là gì?


27

Có một số trò chơi cho phép người chơi viết / tạo tập lệnh trong trò chơi, ví dụ: Kỹ sư không gian hoặc Psi .

Tôi muốn sử dụng một cái gì đó tương tự như một trong hai, nhưng tôi đã gặp khó khăn trong việc tìm kiếm thông tin vì vậy câu hỏi của tôi là:

Có một nhánh lập trình bao gồm khả năng của một phần mềm được biên dịch để chạy mã mới do người dùng tạo ra không?

Theo nhánh lập trình tôi có nghĩa là một cái gì đó giống như PTG (Tạo địa hình thủ tục).

Để tránh quá rộng câu hỏi hoặc ý kiến ​​dựa trên , hãy để tôi nói rõ rằng tôi không tìm kiếm hướng dẫn hoặc địa điểm để tìm hiểu, tôi muốn tên hoặc định nghĩa (nếu có) của công nghệ có liên quan.


22
Chà, có lẽ là "Viết thông dịch viên"?
MatthewRock

2
Gần đây tôi đã trả lời một câu hỏi tương tự , thảo luận về " Máy ảo " là thuật ngữ cho hệ thống chạy mã người dùng và cũng tham khảo bài viết Mẫu lập trình trò chơi trên Mẫu mã byte như một phương tiện để thực hiện điều này nhanh hơn trình thông dịch thông thường.
DMGregory

3
Nó thường được gọi là "kịch bản". Bạn sẽ tìm thấy nhiều tài liệu về cách triển khai kịch bản trong trò chơi, cũng như rất nhiều mẫu mã nguồn mở và đa dạng. Trong phạm vi rộng hơn, có toàn bộ lĩnh vực lập trình trình biên dịch (bao gồm từ vựng, phân tích cú pháp, biên dịch, liên kết, giải thích ...). Trong phạm vi rộng nhất (không nhất thiết phải hữu ích), điều này đòi hỏi khá nhiều bất kỳ tương tác người dùng nào mà ứng dụng của bạn có - một công cụ tạo tập lệnh thực sự chỉ là một cách phức tạp hơn nhiều để chọn từ menu.
Luaan

2
Một chương trình Python có thể lưu trữ các tập lệnh Python. Đó gọi là siêu lập trình. Hầu hết các ngôn ngữ được giải thích có điều đó.
dùng6245072

1
AFAIK trong Space Engineers, mã được biên dịch mã C # trong môi trường hộp cát (trò chơi là mã nguồn mở, do đó bạn có thể kiểm tra cách hoạt động trực tuyến: github.com/KeenSoftwareHouse/SpaceEngineers ). Về cơ bản, trò chơi vận chuyển với trình biên dịch C # và mã chỉ cho phép truy cập vào các chức năng API của trò chơi, do đó phạm vi của chương trình chỉ giới hạn cho bạn. Và nếu bạn đang chơi nhiều người chơi, thì mã chỉ chạy trên máy của bạn (những người chơi khác / máy chủ chỉ nhìn thấy hậu quả ingame)
Florian Castellane

Câu trả lời:


42

Các tập lệnh được viết bằng các ngôn ngữ script / nhúng / phiên dịch như "Lua", "Lisp" hoặc "AngelScript" ( thêm ở đây ) có thể được cập nhật trong trò chơi [*] và sau đó được diễn giải (= thực thi) một cách nhanh chóng.

Bạn có thể liên kết các phần tử từ các tập lệnh đó với mã hóa được biên dịch riêng (C ++, v.v.) để các tập lệnh có thể thực thi logic từ ứng dụng của bạn. Ví dụ. một lệnh cụ thể mà người dùng có thể đưa vào tập lệnh, kết quả là di chuyển nhân vật trong trò chơi theo một khoảng cách nhất định trong thế giới trò chơi.

Một số câu hỏi liên quan có liên quan:


[*] bởi người dùng là một phần của trò chơi hoặc cũng bởi các nhà phát triển để lặp lại / kiểm tra nhanh mà không cần khởi động lại ứng dụng


14
Tôi sẽ cẩn thận khi gọi một cái gì đó "ngôn ngữ diễn giải". Tốt nhất nó là thuật ngữ rất gây tranh cãi.
wonderra

1
Computercraft (mod minecraft) sử dụng LUA làm ngôn ngữ kịch bản để lập trình các tác vụ trong trò chơi.
Tikeb

20
Tôi không thực sự hiểu sự ồn ào. Lisp có thể được giải thích và biên dịch. Chúng tôi không ở đây để từ chối cách phân loại các ngôn ngữ và liệu đó có phải interpretedlà một sự hài lòng tốt hay không; chúng tôi đang nói với OP, người không biết về thực tế này rằng ngôn ngữ không cần phải được biên dịch, nhưng có thể được giải thích - và chúng tôi đưa ra một số ngôn ngữ làm ví dụ. Là Lisp giải thích? Vâng. Nó được biên dịch? Cũng có! Nhưng đó là ngoài phạm vi. Câu trả lời có thể không chính xác với từ ngữ, nhưng mục đích của nó là tốt; nó đẩy OP đi đúng hướng, và đó mới là điều đáng quan tâm. Ở đây, lấy +1 của tôi.
MatthewRock

1
Ngay cả khi một ngôn ngữ chỉ được biên dịch, điều gì ngăn bạn nhúng IDE, trình biên dịch và thời gian chạy vào trò chơi của bạn? Ngoại trừ ngân sách, đó là.
Ordous

3
@DanielJour Mặc dù tôi đồng ý rằng về mặt lý thuyết, một ngôn ngữ có thể khác với cách triển khai của nó (được biên dịch thành mã máy so với mã được mã hóa cho vm), vẫn là một giả định tiết kiệm thời gian hữu ích mà C được biên dịch trừ khi bạn có thể chỉ định ( ngoại hình bạn sẽ nhận được nếu bạn hỏi, "chờ đợi, biên dịch C hoặc giải thích C?" mỗi lần). Đối với mục đích của OP, anh ta cần xem xét các ngôn ngữ hỗ trợ giải thích; dù chúng có thể được biên dịch hay không là một vấn đề vì đó không phải là cách anh ta sẽ sử dụng nó.
Blackhawk

12

Ngôn ngữ nhúng là thuật ngữ kỹ thuật thích hợp. Trên thực tế, ngôn ngữ được sử dụng trong các ứng dụng khác (chẳng hạn như các trò chơi) thường được gọi là kịch bản hay thậm chí giải thích ngôn ngữ, mặc dù họ nên không nhất thiết phải được giải thích hoặc sử dụng cho việc tự động hóa các nhiệm vụ thường xuyên. Googling "ngôn ngữ kịch bản cho trò chơi" có thể sẽ mang lại kết quả hữu ích hơn so với tìm kiếm "ngôn ngữ nhúng".


11

Bạn đang tìm cách thay đổi mã thành một số hành động. Đây chính xác là những gì các thông dịch viên đang làm.

Hãy nhìn vào Python. Bạn chạy nó, và bam! Bạn hạ cánh ở REPL ( R ead E val P rint L oop).

Bạn xác định một chức năng "xin chào" in "Xin chào, thế giới". Và bạn có nó rồi đấy!

Lưu ý rằng bạn đã không biên dịch bất cứ điều gì; thông dịch viên đã thực hiện một số phép thuật để tạo chức năng một cách nhanh chóng (trong thời gian chạy) và bây giờ bạn có thể gọi nó.

Điều tương tự cũng áp dụng cho các trò chơi. Thay vì có REPL, bạn có một trò chơi với mô-đun REPL. Trò chơi có thể bắt đầu REPL và sau đó chạy mọi thứ khác trong REPL này, vì vậy bạn có quyền truy cập vào dữ liệu và có thể chủ động sửa đổi nó.

Nếu bạn đang làm việc với các ngôn ngữ lớn như C ++, chúng có xu hướng kém năng động hơn và có thể được biên dịch. Bạn muốn một số dễ dàng hơn. Bạn có thể tạo ngôn ngữ của riêng mình hoặc sử dụng một số ngôn ngữ hiện có (như CoffeScript, Squirrel, Lua, Scheme, ...)

Chúng thường được gọi là ngôn ngữ kịch bản , vì bạn sử dụng chúng để viết các tập lệnh được xây dựng trên công cụ trò chơi được phát triển bằng một số ngôn ngữ khác (ví dụ: C ++).


2

Nếu ngôn ngữ lập trình trong trò chơi chỉ được thiết kế cho mục đích của trò chơi, thì đó là ngôn ngữ dành riêng cho tên miền .

Ưu điểm (và nhược điểm) của các ngôn ngữ cụ thể trong miền là ngôn ngữ có thể giới hạn những gì người dùng có thể làm (nghĩa là bạn có thể không cho phép kết nối với internet). Bạn có thể thiết kế một ngôn ngữ giúp cho các tác vụ trò chơi thông thường trở nên dễ dàng hơn so với ngôn ngữ có mục đích chung. Nhược điểm là người dùng phải học một ngôn ngữ mới.

Chỉ cần chạy mã người dùng không được xác nhận bằng ngôn ngữ mục đích chung (như python hoặc perl) từ trong trò chơi của bạn, có thể cho phép người dùng lộn xộn với những thứ mà anh ta không nên lộn xộn. Nhưng nó phụ thuộc vào trò chơi của bạn. Nếu bạn không phiền người dùng làm những việc như mở cửa sổ mới từ trong trò chơi của bạn hoặc bất cứ điều gì họ thích, bạn có thể sử dụng ngôn ngữ cho mục đích chung và phơi bày các ràng buộc với các tính năng nhất định trong thế giới trò chơi của bạn.


1

Có hai ví dụ mà tôi có thể nghĩ ra khỏi đỉnh đầu. Cả hai dường như làm chính xác những gì bạn yêu cầu.

Đầu tiên là screeps. https://screeps.com/ Bạn có thể đọc rất nhiều về cách nó hoàn thành mục tiêu này tại http://support.screeps.com/hc/en-us/articles/205960931-Server-side-arch architecture-overview

Thứ hai là ComputerCraft http://www.computercraft.info/ Họ không đi sâu vào chi tiết về cách thức hoạt động nhưng có thể thấy một chút tại wiki của họ http://www.computercraft.info/wiki/Main_Page

Về bản chất, trò chơi chính chạy một trình thông dịch theo một luồng riêng biệt, sau đó cho phép luồng đó điều khiển thế giới trò chơi thông qua các lệnh gọi API.

Trong cả hai ví dụ, trong khi ngôn ngữ gần như không giới hạn (chỉ một số cuộc gọi bị chặn vì lý do bảo mật), các thao tác API bị giới hạn bởi các lệnh gọi API có thể được thực hiện.

Thông thường rất ít công việc được yêu cầu để có được một cái gì đó như thế này bắt đầu. Bạn cần

  • một trình quản lý luồng bảo vệ vòng lặp trò chơi của bạn (không để một luồng khóa vòng lặp hoặc tiêu thụ nhiều tài nguyên). Cả hai ví dụ đều sử dụng bộ giới hạn dựa trên thời gian.
  • một thông dịch viên để chạy một ngôn ngữ. LUA là khá phổ biến những ngày này.
  • một tập hợp các lệnh gọi API sửa đổi thế giới trò chơi. Điều thú vị là ngôn ngữ lập trình nếu bạn không thể làm gì với nó.
  • thực hiện quản lý tài nguyên. Nói cách khác, một cách để lưu trữ các tệp mã và tham chiếu chúng trong trò chơi.

Không có một nhánh lập trình nào xử lý tất cả những mối quan tâm này. Nhưng bạn sẽ cần một nền tảng vững chắc trong đa luồng và kiến ​​thức chung về cách một phiên dịch viên làm việc.


0

Tệp thực thi được biên dịch phải chứa trình phân tích cú pháp có thể đọc mã chương trình bên ngoài . Mã chương trình không cần phải trông giống như C hoặc Python hoặc xyz - nó có thể là bất kỳ loại dữ liệu mô tả nào phù hợp cho mục đích được đề cập. Ví dụ như Thụy Điển, hoặc morse.

Mã chương trình bên ngoài cần phải có một cú pháp , để trình phân tích cú pháp hiểu nó khi nó đọc ký tự theo từng ký tự. Cú pháp có thể mô tả (và mã số có thể chứa) định danh, các giá trị số, các nhà khai thác vv .

Trình phân tích cú pháp được cố định (biên dịch) nhưng nó hoạt động trên mã bên ngoài linh hoạt.

Tệp thực thi được biên dịch phải có API nội bộ với chức năng có liên quan. để trình phân tích cú pháp có thể thực hiện các hành động. Nhiều khả năng cũng phải có quyền truy cập (hai chiều) vào dữ liệu nội bộ của tệp thực thi hoặc trình phân tích cú pháp phải cung cấp một số loại lưu trữ dữ liệu và vệ sinh.

Trình phân tích cú pháp có thể đọc mã chương trình bên ngoài khi khởi động hoặc có thể đọc (một phần) nó ad hoc hoặc có thể đọc lại mã trên mỗi khung (sẽ không hiệu quả) hoặc mã thậm chí có thể được gõ bằng tay và được đăng lên trình phân tích cú pháp khi nó sẵn sàng (như: "di chuyển đơn vị X về phía trước 5 bước" [enter]).

Về cơ bản, mã bên ngoài không cố định - nó có thể thay đổi bất kỳ năm, ngày hoặc phút nào, nhưng vẫn không cần phải thực thi lại. Chỉ hành vi kết quả, được lưu trữ bởi thực thi, thay đổi.

Văn bản bạn đang đọc ngay bây giờ là (loại, và thậm chí nhiều hơn nếu nó được nói) được giải thích vì bạn "thực thi" nó trong não khi đọc nó, mà không biết câu tiếp theo nói gì (hoặc thậm chí nếu nó có thể, lén lút thay đổi ngay hiện nay). Trái ngược với Stack Overflow (trước) biên dịch toàn bộ câu chuyện thành mã byte trong bộ não của bạn, sau đó thực thi nó - và sau đó nó không thể thay đổi được nữa.

Các hiện tượng đang diễn ra là giải thích. Viết kịch bản chỉ là hành động tạo ra một deSCRIPTion hoặc viết . Tất cả mã hóa máy tính là kịch bản imo - chúng tôi mô tả những gì chúng tôi muốn xảy ra. Từ "kịch bản" có nghĩa hơi nghiêng, nhưng vì vậy sẽ ổn. Chúng tôi biết những gì chúng tôi có nghĩa là.

Hoàn toàn không có gì bất thường với các ngôn ngữ được giải thích, và đó không phải là một thuật ngữ gây tranh cãi . Vô số trong số họ tồn tại, và một số trong những người lâu đời nhất được giải thích trái ngược với biên soạn. Trong một ngôn ngữ được giải thích, người ta có thể ví dụ gõ bằng tay:

sock = Socket.New (Địa chỉF Family.InterNetwork, SocketType.Stream ProtocolType.Tcp) [ENTER]

... và sau đó đi nghỉ 30 ... không, 45 phút cà phê :-). Khi trở về, "sock" tồn tại và sẵn sàng để sử dụng thêm bằng cách nhập thêm bằng tay hoặc để tự động hóa trình thông dịch tiếp tục với nó.


Có một quan niệm sai lầm phổ biến rằng một ngôn ngữ được giải thích phải chậm. Nó không đúng. Tùy thuộc vào các yếu tố khác nhau làm cho cuộc thảo luận này quá rộng đối với các bình luận, ngôn ngữ được diễn giải có thể chậm hơn hoặc chậm hơn, nhanh như hoặc thậm chí đối với một số thao tác nhanh hơn ngôn ngữ điều khiển được coi là nhanh (thường là C). Ví dụ với socket có thể hoạt động ít nhiều giống như trong C, vì vậy ví dụ này gây hiểu nhầm. Bạn cũng có thể xác định lại các chức năng được biên dịch trong thời gian chạy bằng một số ngôn ngữ và việc diễn giải không chỉ đơn giản là "thực hiện một hướng dẫn tại thời điểm đó".
MatthewRock

Chắc chắn, một ngôn ngữ được thông dịch cũng có thể hoạt động nhanh hơn - sau tất cả, đó là mã byte thực thi và việc thực thi có thể được tối ưu hóa tốt hơn nhiều, tùy thuộc vào tự động hóa của trình thông dịch. Ngoài ra, một số trình thông dịch có thể biên dịch, từ mã, các phần của mã thành mã byte (và thực thi), ad hoc Ví dụ này chỉ là một ví dụ về tự do, "Thực hiện một lệnh tại thời điểm"? Đó là một sự đơn giản hóa, có thể thêm "trong khi mã tương lai là linh hoạt".
Bão tố

Hãy nghĩ về "kịch bản" giống như một kịch bản phim - bạn vẫn cần diễn viên, và những điều này được định nghĩa trực tiếp về mặt sinh học và xã hội học, chứ không phải khoa học sân khấu (mặc dù những điều này cuối cùng dựa trên sinh học và xã hội học), bởi vì những ngôn ngữ này nhiều hơn phù hợp với mục đích đó nhưng không phải mục đích khác :)
rackandboneman
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.