Apa teknologi yang memungkinkan pemrograman di dalam game?

27

Ada beberapa gim yang memungkinkan pemain untuk menulis / membuat skrip dalam gim, misalnya: Insinyur ruang angkasa atau Psi .

Saya ingin menggunakan sesuatu yang mirip dengan salah satunya, tetapi saya kesulitan menemukan informasi sehingga pertanyaan saya adalah:

Apakah ada cabang pemrograman yang mencakup kemampuan suatu perangkat lunak yang pernah dikompilasi untuk menjalankan kode baru yang dibuat oleh pengguna?

Dengan cabang pemrograman saya maksudkan sesuatu seperti PTG (Prosedural Terrain Generation).

Untuk menghindari pertanyaan atau pendapat yang terlalu luas , izinkan saya dengan jelas menyatakan bahwa saya tidak mencari panduan atau tempat untuk belajar, saya ingin nama atau definisi (jika ada) dari teknologi yang terlibat.

Westside Tony
sumber
22
Yah, mungkin "Menulis penerjemah"?
MatthewRock
2
Saya menjawab pertanyaan yang sama baru-baru ini , membahas " Mesin Virtual " sebagai istilah untuk sistem yang menjalankan kode pengguna, dan juga merujuk artikel Pola Pemrograman Game pada Pola Bytecode sebagai cara untuk mengimplementasikan ini lebih cepat daripada penerjemah konvensional.
DMGregory
3
Biasanya disebut "scripting". Anda akan menemukan banyak bahan tentang cara menerapkan skrip dalam sebuah game, serta banyak (berbagai) sampel sumber terbuka dan kode nyata. Dalam lingkup yang lebih luas, ada seluruh bidang pemrograman kompiler (yang mencakup lexing, parsing, kompilasi, menautkan, menafsirkan ...). Dalam ruang lingkup seluas-luasnya (tidak selalu berguna), ini memerlukan cukup banyak interaksi pengguna yang dimiliki aplikasi Anda - mesin skrip sebenarnya hanya cara yang jauh lebih kompleks untuk memilih dari menu.
Luaan
2
Program Python dapat meng-host skrip Python. Itu disebut metaprogramming. Sebagian besar bahasa yang ditafsirkan memiliki itu.
user6245072
1
AFAIK di Space Engineers, kode ini dikompilasi kode C # di lingkungan berpasir (permainan menjadi sumber terbuka, sehingga Anda dapat memeriksa cara kerjanya secara online: github.com/KeenSoftwareHouse/SpaceEngineers ). Pada dasarnya gim ini dikirimkan dengan kompiler C # dan kode hanya memungkinkan akses ke fungsi-fungsi API gim, sehingga cakupan program terbatas hanya untuk Anda. Dan jika Anda bermain multipemain, maka kodenya hanya berjalan di mesin Anda (pemain lain / server hanya melihat konsekuensi yang memalukan)
Florian Castellane

Jawaban:

42

Skrip yang ditulis dalam bahasa scripting / tertanam / ditafsirkan seperti "Lua", "Lisp" atau "AngelScript" ( lebih lanjut di sini ) dapat diperbarui selama game [*] dan kemudian ditafsirkan (= dieksekusi) dengan cepat.

Anda bisa mengikat elemen-elemen dari skrip-skrip tersebut ke kode kompilasi asli Anda (C ++, dll.) Sehingga skrip kemudian dapat menjalankan logika dari aplikasi Anda. E. g. perintah khusus yang dapat dimasukkan pengguna dalam skrip, sebagai hasilnya memindahkan karakter dalam game dengan jarak tertentu di dunia game.

Beberapa pertanyaan terkait yang relevan:


[*] baik oleh pengguna sebagai bagian dari permainan game atau juga oleh pengembang untuk pengulangan / pengujian cepat tanpa memulai ulang aplikasi

Philip Allgaier
sumber
14
Saya akan berhati-hati ketika memanggil sesuatu "bahasa yang ditafsirkan". Paling-paling itu istilah yang sangat diperdebatkan.
Mukjizat
1
Computercraft (minecraft mod) menggunakan LUA sebagai bahasa scripting untuk memprogram tugas-tugas dalam game.
Tikeb
20
Saya tidak begitu mengerti masalah itu. Lisp dapat ditafsirkan dan dikompilasi. Kami di sini tidak membahas cara mengklasifikasikan bahasa dan apakah interpretedklasisifikasi yang baik; kami memberi tahu OP yang tidak mengetahui fakta ini bahwa bahasa tidak perlu dikompilasi, tetapi dapat ditafsirkan - dan kami memberikan beberapa bahasa sebagai contoh. Apakah Lisp ditafsirkan? Iya nih. Apakah sudah dikompilasi? Juga ya! Tapi itu di luar ruang lingkup. Jawabannya mungkin tidak akurat dengan kata-kata, tetapi tidak masalah untuk tujuannya; mendorong OP ke arah yang benar, dan itulah yang terpenting. Di sini, ambil +1 saya.
MatthewRock
1
Yah, bahkan jika suatu bahasa hanya kompilasi, apa yang menghentikan Anda dari menanamkan IDE, kompiler dan runtime ke dalam gim Anda? Kecuali anggaran, yaitu.
Ordous
3
@DanielJour Sementara saya akan setuju bahwa secara teoritis suatu bahasa dapat berbeda dari implementasinya (dikompilasi ke kode mesin vs dikompilasi ke bytecode untuk vm), itu masih merupakan asumsi menghemat waktu yang berguna bahwa C dikompilasi kecuali ditentukan lain (dan dapat Anda bayangkan tampilan yang akan Anda dapatkan jika Anda bertanya, "tunggu, kompilasi C atau interpretasikan C?" setiap kali). Untuk tujuan OP, ia perlu melihat bahasa yang mendukung interpretasi; apakah mereka juga dapat dikompilasi atau tidak merupakan masalah karena itu bukan bagaimana ia akan menggunakannya.
Blackhawk
12

Bahasa tertanam adalah istilah teknis yang tepat. Dalam praktiknya, bahasa yang digunakan di dalam aplikasi lain (seperti permainan) sering disebut sebagai bahasa scripting atau bahkan ditafsirkan , meskipun mereka tidak harus ditafsirkan atau digunakan untuk mengotomatisasi tugas-tugas rutin. Googling "bahasa scripting untuk game" mungkin akan menghasilkan hasil yang lebih bermanfaat daripada mencari "bahasa yang disematkan".

interphx
sumber
11

Anda mencari cara untuk mengubah kode menjadi beberapa tindakan. Inilah yang dilakukan penerjemah .

Lihatlah Python. Anda menjalankannya, dan bam! Anda mendarat di REPL ( R ead E val P rint L oop).

Anda mendefinisikan fungsi "halo" yang mencetak "Halo, dunia". Dan begitulah!

Perhatikan bahwa Anda tidak mengkompilasi apa pun; penerjemah melakukan beberapa sihir untuk membuat fungsi dengan cepat (selama runtime) dan sekarang Anda dapat menyebutnya.

Hal yang sama berlaku untuk game. Alih-alih memiliki REPL, Anda memiliki game dengan modul REPL. Gim ini mungkin memulai REPL dan menjalankan semua yang lain di REPL ini, sehingga Anda memiliki akses ke data dan dapat memodifikasinya secara aktif.

Jika Anda bekerja dengan bahasa besar seperti C ++, mereka cenderung kurang dinamis dan mungkin dikompilasi. Anda ingin lebih mudah. Anda bisa membuat bahasa Anda sendiri, atau menggunakan beberapa yang sudah ada (seperti CoffeScript, Squirrel, Lua, Scheme, ...)

Ini sering disebut bahasa scripting , karena Anda menggunakannya untuk menulis skrip yang dibangun di atas mesin game yang dikembangkan dalam beberapa bahasa lain (misalnya C ++).

MatthewRock
sumber
2

Jika bahasa pemrograman dalam game hanya dirancang untuk tujuan permainan, maka itu adalah bahasa khusus domain .

Keuntungan (dan kerugian) dari bahasa-bahasa khusus domain adalah bahwa bahasa itu sendiri dapat membatasi apa yang dapat dilakukan oleh pengguna (yaitu Anda dapat melarang koneksi ke internet). Anda bisa mendesain bahasa yang membuat tugas gim yang umum lebih mudah daripada dalam bahasa tujuan umum. Kerugiannya adalah bahwa pengguna harus belajar bahasa baru.

Hanya menjalankan kode pengguna yang tidak bersih dalam bahasa tujuan umum (seperti python atau perl) dari dalam gim Anda, dapat memungkinkan pengguna untuk mengacaukan hal-hal yang tidak boleh ia mainkan. Tapi itu tergantung pada gim Anda. Jika Anda tidak keberatan pengguna melakukan hal-hal seperti membuka jendela baru dari dalam game Anda atau apa pun yang mereka suka, Anda dapat menggunakan bahasa tujuan umum dan mengekspos binding ke fitur-fitur tertentu dari dunia game Anda.

TheEspinosa
sumber
1

Ada dua contoh yang bisa saya pikirkan di atas kepala saya. Keduanya tampaknya melakukan persis apa yang Anda minta.

Yang pertama adalah screeps. https://screeps.com/ Anda dapat membaca banyak tentang bagaimana mencapai tujuan ini di http://support.screeps.com/hc/en-us/articles/205960931-Server-side-architecture-overview

Yang kedua adalah ComputerCraft http://www.computercraft.info/ Mereka tidak menjelaskan secara detail bagaimana cara kerjanya tetapi sedikit dapat dilihat di wiki mereka http://www.computercraft.info/wiki/Main_Page

Intinya, gim utama menjalankan juru bahasa di utas terpisah, lalu memungkinkan utas itu memanipulasi dunia gim melalui panggilan API.

Dalam kedua contoh, sementara bahasa hampir tidak terbatas (hanya beberapa panggilan diblokir karena alasan keamanan) manipulasi dibatasi oleh panggilan API yang dapat dibuat.

Biasanya sangat sedikit pekerjaan yang diperlukan untuk memulai sesuatu seperti ini. Kamu butuh

  • manajer utas yang melindungi loop game Anda (jangan biarkan utas mengunci loop atau menghabiskan banyak sumber daya). Kedua contoh menggunakan pembatas berbasis waktu.
  • juru bahasa untuk menjalankan suatu bahasa. LUA sangat umum hari ini.
  • satu set panggilan API yang mengubah dunia game. Apa yang menyenangkan adalah bahasa pemrograman jika Anda tidak bisa melakukan apa-apa dengannya.
  • implementasi manajemen sumber daya. Dengan kata lain cara untuk menyimpan file kode dan referensi mereka dalam game.

Tidak ada satu cabang pemrograman yang menangani semua masalah ini. Tetapi Anda akan membutuhkan dasar yang kuat dalam multi-threading, dan pengetahuan umum tentang cara kerja seorang juru bahasa.

kapas
sumber
0

Executable yang dikompilasi harus berisi parser yang dapat membaca kode program eksternal . Kode program tidak harus terlihat seperti C atau Python atau xyz - bisa berupa data deskriptif apa saja yang cocok untuk tujuan yang dimaksud. Misalnya swedia, atau morse.

Kode program eksternal perlu memiliki sintaks , sehingga parser memahaminya saat membacanya karakter demi karakter. Sintaks dapat menggambarkan (dan kode dapat berisi) pengidentifikasi, nilai numerik, operator, dll .

Parser sudah diperbaiki (dikompilasi) tetapi bekerja pada kode eksternal yang fleksibel.

Executable yang dikompilasi harus memiliki API internal untuk fungsionalitas yang relevan. sehingga parser dapat melakukan tindakan. Kemungkinan besar harus ada (dua arah) akses ke data internal yang dapat dieksekusi juga, atau parser harus menyediakan beberapa jenis penyimpanan data dan tata graha.

Parser dapat membaca kode program eksternal pada startup yang dapat dieksekusi , atau dapat membaca (bagian) ad hoc , atau dapat membaca ulang per setiap frame (tidak efisien), atau kode tersebut bahkan dapat diketik dengan tangan dan diposting ke parser saat bersiap-siap (seperti: "pindahkan unit X maju 5 langkah" [enter]).

Pada dasarnya, kode eksternal tidak diperbaiki - dapat berubah setiap tahun, hari atau menit, tetapi masih dapat dieksekusi tidak perlu dikompilasi ulang. Hanya perilaku yang dihasilkan, yang dihosting oleh yang dapat dieksekusi, yang berubah.

Teks yang sedang Anda baca saat ini adalah (agak, dan bahkan lebih jika itu diucapkan) ditafsirkan karena Anda "mengeksekusi" itu di otak Anda saat membacanya, tanpa mengetahui apa kalimat berikutnya mengatakan (atau bahkan jika mungkin, secara diam-diam berubah dengan benar sekarang). Berbeda dengan Stack Overflow (pre) yang mengkompilasi seluruh cerita menjadi bytecode di otak Anda, yang kemudian mengeksekusinya - dan ofc maka tidak bisa berubah lagi.

The Fenomena yang terus menerus adalah interpretion. Scripting hanyalah tindakan membuat deSCRIPTion, atau menulis . Semua pengkodean komputer adalah skrip imo - kami menjelaskan apa yang kami inginkan terjadi. Kata "scripting" memiliki arti yang agak miring, jadi baiklah. Kami tahu apa yang kami maksud.

Sama sekali tidak ada yang luar biasa dengan bahasa yang ditafsirkan, dan itu sama sekali bukan istilah yang bisa diperdebatkan . Banyak dari mereka ada, dan beberapa yang paling tua ditafsirkan sebagai lawan kompilasi. Dalam bahasa yang ditafsirkan, misalnya seseorang dapat mengetik dengan tangan:

sock = Socket.New (AddressFamily.InterNetwork, SocketType.Stream ProtocolType.Tcp) [ENTER]

... dan kemudian pergi untuk 30 ... tidak, istirahat kopi 45 menit :-). Ketika kembali, "kaus kaki" ada dan siap untuk digunakan lebih lanjut dengan mengetik lebih banyak dengan tangan, atau membiarkan otomatisasi penerjemah melanjutkannya.

Angin badai
sumber
Ada kesalahpahaman umum bahwa bahasa yang ditafsirkan harus lambat. Itu tidak benar. Bergantung pada berbagai faktor yang membuat diskusi ini terlalu luas untuk komentar, bahasa yang ditafsirkan bisa menjadi lebih besar atau lebih lambat, secepat, atau bahkan untuk beberapa operasi lebih cepat daripada bahasa kontrol yang dianggap cepat (biasanya C). Contoh dengan socket mungkin akan bekerja kurang lebih seperti di C, jadi contohnya adalah menyesatkan. Anda juga dapat mendefinisikan kembali fungsi yang dikompilasi pada runtime dalam beberapa bahasa, dan menafsirkannya tidak hanya berarti "menjalankan satu instruksi pada saat itu".
MatthewRock
Tentu saja, bahasa yang ditafsirkan dapat berkinerja lebih cepat juga - setelah itu bytecode yang mengeksekusi, dan eksekusi mungkin jauh lebih baik dioptimalkan, tergantung pada otomatisasi penerjemah. Selain itu, beberapa penerjemah dapat mengkompilasi, dari kode, bagian kode ke dalam bytecode (dan mengeksekusi), ad hoc Contohnya hanyalah contoh dari kebebasan, "Pergi satu instruksi pada waktu"? Nah itu penyederhanaan yang berlebihan, mungkin menambahkan "sementara kode masa depan fleksibel".
Stormwind
Pikirkan "naskah" lebih seperti naskah film - Anda masih memerlukan aktor, dan ini didefinisikan secara langsung dalam hal biologi dan sosiologi, bukan ilmu teater (meskipun pada akhirnya ini didasarkan pada biologi dan sosiologi), karena bahasa-bahasa ini lebih cocok untuk tujuan itu tetapi tidak yang lain :)
rackandboneman