We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

Bringing Python to Godot game engine

00:00

Formal Metadata

Title
Bringing Python to Godot game engine
Title of Series
Number of Parts
160
Author
License
CC Attribution - NonCommercial - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Identifiers
Publisher
Release Date
Language

Content Metadata

Subject Area
Genre
Abstract
Bringing Python to Godot game engine [EuroPython 2017 - Talk - 2017-07-10 - PyCharm Room] [Rimini, Italy] https://godotengine.org/ Godot is an advanced, feature-packed, multi-platform 2D and 3D open source game engine. The project has joined the Software Freedom Conservancy project and it growing community makes it hopes to become a real alternative to Unity&GameMaker. This talk cover a year long journey of the port of Python as a scripting language for the engine, starting from a rant against Godot's Python-like proprietary language. We will have a look at Godot's internal architecture as is it itself a real interpreter with it garbage collector, dynamic typing, introspection and even builtin custom scripting language. All of this having to work next to our Python interpreter and communicate back and forth with it. Finally we will see the different approaches that have been tried to bind Python to Godot each with there own pros&cons: Using Micropython interpreter instead of CPython Using PyBind11 to statically bind to Godot C++ API Using CFFI and rely on a 3rd party C API The audience should have some basic knowledge of C level computing (static vs dynamic language, compilation & linking)
Game theorySoftwareIntelState of matterWeb 2.0Computer programmingLevel (video gaming)Game theoryMultiplication signComputer animationLecture/Conference
Lemma (mathematics)Dew pointGame theoryMultiplication signComputer programmingWeb 2.0Existence
Closed setWindowGodSource codeGame theoryoutputBoilerplate (text)Directed graphBinary codeScripting languagePhysicalismBoiling pointArithmetic meanComputer animation
Electronic data interchangeDemo (music)Multiplication signGame theoryFormal languageComputing platformDemosceneBitLevel (video gaming)Category of being1 (number)Scripting languageCuboidDomain-specific languageRoundness (object)Computer animation
DemosceneLogical constantException handlingFunctional (mathematics)Category of beingDatabase normalizationLevel (video gaming)PhysicalismGame theoryBitSource codeComputer animation
Demo (music)Multiplication signGame theoryFormal languageDampingScripting languageCASE <Informatik>Order (biology)Computer animation
AerodynamicsOvalModemDemosceneCodierung <Programmierung>CASE <Informatik>Functional (mathematics)CompilerModule (mathematics)Run time (program lifecycle phase)Category of beingCodeBytecodeDynamical systemFormal languageSocial classMacro (computer science)RotationSpacetimeScripting languageInterpreter (computing)Object (grammar)Arrow of timeClassical physicsError messageInformationKeyboard shortcutSource codeGame theoryData structureCore dumpInterface (computing)Multiplication signVariable (mathematics)Medical imagingDampingState of matterEndliche ModelltheorieRight angleServer (computing)Moment (mathematics)Computer animationXML
Electronic data interchangeGame theoryMultiplication signVirtual machineLibrary (computing)Unit testingLogicExecution unitSoftware testingAngle
Data conversionCryptographySocial classFormal languageGame theoryDynamical systemSemiconductor memoryInterpreter (computing)Object (grammar)Multiplication signDifferent (Kate Ryan album)Social classView (database)Point (geometry)Presentation of a groupIntegrated development environmentType theoryTemplate (C++)Library (computing)Data compressionCodeMetropolitan area networkState of matterFunctional (mathematics)Order (biology)Goodness of fitReading (process)Level (video gaming)Compilation albumImplementationComputational fluid dynamics1 (number)MassString (computer science)Generic programmingSpeicherbereinigungPhysical systemKeyboard shortcutMicrocontrollerScripting languagePiSymbol tableMoment (mathematics)Programmer (hardware)Run time (program lifecycle phase)GodStaff (military)Green's functionModule (mathematics)XML
DisintegrationText editorMathematicsGame theoryDemosceneScripting languageSoftware testingWordTemplate (C++)Artistic renderingOrder (biology)Roundness (object)Loop (music)CASE <Informatik>Goodness of fitModule (mathematics)Point (geometry)Revision controlMoment (mathematics)BitBinary codeComputer fileReal numberComplete metric spaceForcing (mathematics)Projective planeCuboidLine (geometry)Beta functionKeyboard shortcutFunctional (mathematics)Just-in-Time-CompilerData integrityCompilerMultiplication signAxiom of choiceSource codeLattice (order)Endliche ModelltheorieElectronic signatureCodeINTEGRALText editorBuildingSoftware bugAlpha (investment)Raw image formatSoftware developerSocial class
Network topologySet (mathematics)Video game consoleComputer animationSource code
CAN busBeta functionText editorDisintegrationDebuggerCodeOrder (biology)Text editorCoalitionCodierung <Programmierung>UsabilitySpherical capComputer animationXML
Text editorDisintegrationBeta functionScripting languageModule (mathematics)Structural loadOrder (biology)Computer programmingGame theoryGodField (computer science)Programming languageTraffic reportingLibrary (computing)Ferry CorstenTupleWindowInfinitySocial classJSONXML
1 (number)ACIDMoment (mathematics)Data storage deviceState of matterProjective planeSource codeComputer animation
Game theoryWavePairwise comparisonMultiplication signJSONXMLLecture/Conference
Keyboard shortcutCASE <Informatik>Software testingBit rateGame theoryoutputMobile WebLecture/Conference
MereologyOnline helpCASE <Informatik>Shared memoryoutputComputer programmingAndroid (robot)Binary codeScripting languageGame theoryLinear regressionINTEGRALNP-hardOrder (biology)Distribution (mathematics)CodeLecture/Conference
Transcript: English(auto-generated)
He's Emmanuel Lebon. Please welcome him on stage. So hi, everyone. Thank you for coming. Welcome to this conference. First, let me introduce myself.
I'm Emmanuel. Most of the time, I'm not doing game programming. I'm doing web stuff. It's kind of a hobby for me. I'm the kind of people, you know, which every six months, I get a really great idea for a game. And so I'm like, oh, I have today to do that. And so I start working on the game. And after like two months and end up, I realize I spent all my time making a game engine
and not a game. So I get pretty disappointed, and I drop it. And so last time, I had this kind of really great idea. I said, OK, this time, I won't mess up. I will just take an existing game engine and focus 100% on my game. And that's how I met Godot. So what's Godot?
Godot is a full feature. It's just like one binary which gets everything in the sink all around in just one package. So there is plenty of features like physical engine, 2D, 3D rendering, audio engine, scripts. You can do profiling. You have the input, which is managed for you.
Basically, you have all the hassles, the boil plates, which are all already done for you and you just focus on the game. The other really great features about Godot, it's a pencils. It's a MIT license, meaning you can basically do your own game close.
You can sell it. You have not to pay anything. And one thing which was really important for me, it has Linux support. So you don't have to go to Windows and develop a game on Windows because it's kind of boring. So now it's time for a little demo on what Godot looks like.
So it's basically, if you're already according to Unity game engine, it looks kind of the same. So you have this panel, which is your main scene of the game. I can zoom out. There is a bit too much. There is my level. So basically, what you do by building a game
is you create this scene with plenty of node. So you can see on the right side, you have node for basically everything. So here is kind of bonus. It's coin because we're on platform game. Every enemy are also, sorry. Every enemy is also a node like this.
You can customize every node here with plenty of properties. One great thing about Godot is you can nest scenes inside scenes. So what does it means is, for example, this enemy right now in our main scene, it looks like it's just a simple node. But in fact, if we look at it, it's much more complex.
In fact, our little guy, he's composed of plenty of nodes, so it itself a scene. You can see that there is a hitbox here, for example. There is a sprite, there is animation, and now we can tweak this little guy how we want. For example, I can show the working animation
and work on it like that. Another thing I can do is to plug scripts on any node I want to extend it. So for example, we can see on enemy, it has a script here. It's a custom language which is called GDScript.
It's kind of lookalike Python. It's inspired by Python, but it's not Python. So there is no self keyword, for example. There is constants. We'll get about it later. So with this script, I can extend what the node can do.
I can attach new property, for example. I can create new function, connect to signals, et cetera, et cetera. So if I go back to my main scene here, so I can start messing a bit around. I can move this guy here. I can change a bit the map, how it looks like.
I didn't think like that. I can, for example, add a new coin scene here just to put the coin. And if I'm good, I can start running the game. So here it is. It didn't crash. Incredible. And so here it is.
I have my game engine with all the physics already done. You see I'm really pretty poor about it. And so yeah, it just works. So one thing about the game engine is GDScript. It's always a question that occur every time is why is it so? Why did I just create from scratch a new game language,
a new script language, reinventing the wheel instead of just taking Python or taking Lua, which is already designed for this kind of use case? In order to answer this question, we should look at how Godot works from the inside. So if we look at, I said later that in Godot you have your scene and everything is a node.
So if we look at, for example, a 2D node, which is basically you get a node and you add some property to move it into a 2D space. So for example, here you have a rotation. So for the moment, it's really simple C++ code. But what you do in Godot is you add this macro GD class
and this function bind method. And basically what you're doing by doing this is you add introspection into your class. So now with these things, you can do two things. If you want to create a game only using C++ to connecting to the C++ Godot API,
you can do it just the classical C++ way, just like this. So you use a new keyword, you create an object and then you use arrows to call the function. Or you can go through this thing which is called class DB, this singleton.
And using the singleton, in fact, you go dynamically. So it's during runtime that you will ask the game engine, you ask class DB to retrieve the class which is named node 2D to instantiate it. And then after that, you ask to retrieve the function set rotation and to apply it to this object.
And if you apply, for example, the wrong function to the wrong object, it won't blow up like a segfault or something like that, you just end up with an error object you can handle nicely. You can see all around there is those variant object. If you think about it, I mean,
just like in Python, in fact. In CPython, you have just your CPython interpreter which has not been compiled by you and you have your script. Everything, every variable in your script is represented inside CPython as a pi object structure. And so this pi object can contain basically everything,
a float, an object, a class, et cetera. So it's just like this in Godot. You have this variant class which contain anything. So what's about GDScript? GDScript looks really simpler than the dynamic interface but in fact is exactly the same thing.
It's just a convenient way to wrap the C++ dynamic API of Godot. So putting another way, you can see that you have on the left what is the core functionality of Godot which is so this variant class which contain basically anything and this class DB structure which can contain
all the information you can retrieve at runtime about the node. And on the right side, you have a really simple GDScript module which is basically two thing. One is a compiler to turn your Godot human readable source code into bytecode.
And another thing is just a really tiny interpreter which take every bytecode one by one and just call the equivalent code which is provided by class DB. So in the end, it's a really simple module. It's something that is not like you think a really big interpreter with plenty of property
and functionality and so on. It's just something really tiny, really simple and it's deeply integrated with Godot so it works pretty well. So there is nothing to fear about this GDScript. It's one of the few use case where inventing a new language is fine.
But we're here for Python, not for GDScript. And in fact, I really love Python and when I start using this game engine with Godot, with GDScript, sorry, I was always thinking about Python saying, oh, we could do this better in Python. For example, I could take this game logic outside of the engine and start unit testing it
with pytest so it would be much more easier to do this thing. I could also, for example, plug the Python ecosystem into my game, for example, start using the PyTorch library to use machine learning to create AI or advanced stuff like that.
So I end up realizing what I really wanted is I should spend a couple of week, maybe a month, into trying to put Python into Godot and then after that, I will go back to my game and the time I will save because now I have Python and Godot will really worth it and so I will recover my time,
invested into doing this. So now, how do we do that? The first thing we have to do is to tell Godot there is a new player in the game which is Python and if it finds out that he's asked to load a .pi file, it should come to see our module. So doing this is pretty simple.
There is already a generic class in Godot which represent what script language is and so we have to implement this. The second thing is we have to create bindings. So we have to create binding class for Python to manipulate Godot object. So there is pretty simple object like bolding, like mass vector, for example,
and there are more dynamics one like the node I was telling you before. So for the node, we can use the class DB API to create the binding just lazily only when they are needed at runtime. The only trick we have to make sure about it, with those things is we must be sure to manipulate
the Godot object through our binding and not copy the data because most of the time you get data from Godot, you start modifying them a bit, you return them to Godot and then Godot is doing stuff, reading it, modifying it, et cetera. Next thing is converting variant into pi object.
So the way Godot represent dynamic type into the way Python represent dynamic type, so it's really straightforward, there is no really big deal about this. And the much more complex thing is handle memory because now we end up with two different garbage collector, one for Godot and one for Python
and we have to make them work all together and most of the time what happens is you start creating an object from inside Python, for example, you pass it to Godot and so from the Python point of view there is not much about it, about this memory, so it can start to clean it, to erase it
and so it's brought up at any time when Godot start to actually read those data. So we have to take care about this. Now we can talk about the implementation. So I said I was planning for something like one month, let's say, to implement this.
It didn't well as planned, so it's been one year now. So I start up at the really beginning using MicroPython. The reason why it's first, the guy behind Godot, they already tried to put Python on Godot and they said the binding was a real pain in the ass and so it was a lot of time and the code wasn't really elegant
so it didn't work at all. So I said okay, let's try something else. The good thing about MicroPython seems there is a lot of customization you can do when you choose to build it. You can disable plenty of feature in order to have your interpreter consume less RAM and have less functionality. So maybe you can sing making a sandbox
because you reduce a lot of functionality of your scripts. So it seemed really interesting. The trouble about it is MicroPython is designed to be run on microcontroller. So on system which are really limited with memory, which is not what you do when you are running a game.
Basically you have gigabytes of RAM. So the trouble with this is the C API is really lower level than it would be with C Python for example. So for example when you are working with strings, you are not really working with strings. Most of the time the strings are all collected together
and during the compilation time, MicroPython is looking for if there is some string that are reused from time to time and if they are the same, they just all connect them together. And so in the end you don't manipulate a string. You just manipulate an ID on the string. So everything like this in MicroPython. So it make the API much more difficult to work with.
And so yeah, it was really hard to work. The other thing is it's not 100% Python. So I said I wanted to have all the really nice Python ecosystem with it. But with MicroPython for example, you don't have the same C API.
You don't support really dynamic stuff. So there is plenty of libraries that won't work with MicroPython. One example is for the moment, there is no support for the PDB library which is understandable when you think about it because MicroPython, it's for microcontroller
and when you run your code on the microcontroller, you don't have access to SDN, SDL. You just don't debug it with PDB. But when you are working with a game, it's much different. You really want to be able to just put a PDB everywhere and jump in and start doing introspection and so on. So it was not the really best idea.
So around this time, we got the Folsdam in Belgium. And just after the Folsdam, still in Belgium was really first GodoCon. So all the Godo programmers met there. It was a really fun time, especially because it's Belgium and so you eat fries and you drink beer, which is really good for programmers. And so we had a lot of IDE
and so I realized MicroPython just won't do it. And so I switched to CPython with PyBean 11. PyBean 11 is a C++ library which is kind of, it does kind of magical tricks with C++ templates. So basically, you have your C++ class,
you wrap it with PyBean 11, and you magically end up with a Python module. So it works really well. It's really elegant. You feel like you are working with Python from within C++. But the trouble is you are doing really static templates.
So you have your C++ class, you bind it and then you get it into Python. But the way Godo works is much more dynamic. Like I said, you have these class DB things when you can do introspection. But you cannot use it here with PyBean 11. So in the end, I end up having to write a script
which pass all the source code of Godo in order to get back the C++ API and then generate a glue code for scripts for bindings. So in the end, it was like 100,000 lines of C++
with templates everywhere generated. The completion of this was a real nightmare. It was something like five minutes just for this file with five gigabytes of RAM used. And in the end, you add up to 100 megabytes to your final binary.
So it works, but it was really not elegant. And really cumbersome to work with. I mean, every time I had to do just a simple change, I have to wait more than five minutes just to see the recompilation. So yeah, it was kind of painful.
But any time, there was always a Godo community was always there. And so we had a new meeting at Mozilla in Paris. We even have the main developer of Godo which is from Argentina. So we cannot see him in person normally, but he went there with his wife for his vacation.
It was kind of really nice. And so we talk a lot about all the troubles. And so I end up, there was a new feature inside Godo which was they created a C API built on top of the C++ API. And so it was a real game changer
because with this C API, I could just drop everything and switch to CFFI, which was a really good choice if you saw the conference from in Russia this morning. So basically, CFFI is solving every problem. What you do is just you create a script. In this script, you say, I want to use from into Python
this function and this function. You just copy paste the function signature. Then you put your Python code. You say, okay, I want to embed this code into my module. And you end up with defining, okay, I want this Python function to look like this function
into C if it calls from C. Then you run the script and you end up with one C file. You just have to compile and you get your module. The absolutely great thing about this is most of your binding are done now in Python. So it means that you have no longer to compile.
You just compile once and given all your, most of your code is Python, you just load it dynamically. And so you can change everything at any time and you don't have to recombine. So compared to PyBin 11, it was like a game changer. On top of that, you got PyPy for free,
which means the compatibility is here. It's really cheap and so, yeah, just, I mean, PyPy is just a really good use case for, I mean, game engine is a really good use case for PyPy because it's always the same loop which is run, always the same script, the same data. The just-in-time compilation can really do a boost.
So I hope it will make a boost eventually in Godot. So you are here and now we have a beta which is available. It was released last week in a hurry because we have this conference and so I have something to show. But it works really well. I didn't find any bugs so far,
but that's why we need you to find the bugs. I'm sure there is plenty of them. Yeah, the other thing is PyPy. So I said it would be a really, really nice feature to have it. The only really problem is, for the moment,
I'm using the new version of Godot because Godot is kind of a really young project. I mean, it's been open-sourced in 2014. So it's been three years. They work a lot on it. So there is plenty of new feature. This new release which is a 3.0 which is coming soon.
It will change a lot of things. They all change the 3D renderer, for example. They have a new physically-based rendering. They have now the scenes. I mean, they change a lot, a lot of things. The thing is, now the release is in alpha. So I got Godot in alpha. I got my module which is really early.
So I believe it is a beta. And now I'm building with this PyPy which is in beta also for PyPy 3.5. So we have one alpha, two beta all together, and so it end up with a big segfault. But it built.
So we have to find out, and then we're good to go. Next thing would be editor integration because right now it's kind of raw. If you see, like I said, the editor is really nice because everything is packed together so it looks really interesting. But right now, if I want to debug my script,
I put PDB somewhere, for example. It's not like that. You have to go to the console, like this ugly console, and use PDB like that. It would be much better to be able to use the debugger panel here in order to do the stuff.
Another nice thing would be to have autocompletion for the Python code into the built-in editor in Godot. And last but not least, I think the most important thing would be to add, I mean, right now, the C API I use with CFFI is not complete enough.
I have access to the built-in, I have access to the ClassDB stuff, to my introspection. But the way I register my module to Godot to say, okay, there is a new module for a programming language, for a script language on the program, I'm still using C++.
So what does it mean is I have to release an interior engine I compile myself with the support of Python, and I have to give it to people, which is really cumbersome, because I should support Windows, I should support Linux, Mac OS, and et cetera.
And it's not like the philosophy of Godot is you have just one binary, and then you just kind of use it. You don't have to recompile stuff, and so on. So the really important thing I think I'm going to work on is to improve the C API in order to just be able to compile Godot as a shared library,
just a simple .s or stuff, which you can just drop on your game folder, and then Godot will see these things with load it, and then you got the Python support, like that. The really good things would be to have it in the asset store, because you can see on Godot
you have an asset store, just like in Unity. For the moment, it's snippets of COD, of GDScript's COD, but it would be really good, you know, you start your new project, you go on the asset store, you double-click on the Python, and then you got your Python just like that. So that would be the final goal.
And I think if I finish this, I could go back to working my game. I totally forgot what it was about, by the way. Yeah, so thank you very much. Just one more thing, I will be old this week
on your Python, and I will also be on the sprint, which are this weekend, so if you're interested in the project and want to hang out, just tell me and we will code all together. Thank you. Okay, we've got some time for questions. If you have one, please raise your hand. We have a microphone.
Thank you for the talk, and of course question is what about performance in comparison to GDScript? There is two thing. First is, GDScript is already known to be slow.
I mean, there is people complaining about it. Now we have no idea if it's because it's really slow or because people are just comparing GDScript to C++. So there need to be some tests which needs to be done, but nobody has done them yet. So maybe if I run benchmark, right now Python is faster
than GDScript even if there is a big binding because GDScript is not optimized. But I don't think it's the case. But anyway, I think to improve the performance on this binding, there is PyPy. So that's my hope.
I wish really hard that PyPy will make Python really fast and so the binding layer which makes things slower but not that slow because you get a boost from PyPy.
Do you support mobile export, like iOS or Android? You mean to support Android? Or iOS? Yeah, yeah, yeah, we support iOS, we support iOS. This engine has been used for releasing the Mr. Bean game
on Android and iOS, for example. You can play it, it's free. I don't have share on it. This may be a related question, but does Godot make it easier to distribute games for PC?
And does your Python integration and PyPy stuff make it harder to distribute games? Sorry, I didn't get your question. Could you speak lower, please? So when you want to publish games for people to use and you want to use them on PC,
does Godot help with that? And does using PyPy or CPython as part of a Godot game make it harder to publish games? Basically, when you release a game, it's just like you have your folder which contain your assets and your scripts
and you put the binary of Godot, just the program, you just put it inside your folder and you're good to go. Everything is okay, everything works. There is more advanced way to do it if you want, for example, to strip your code in order not having people can easily read what it is.
There are more advanced, but you can also do. I think now there are people working on supporting the Steam API to release game with Steam. So yeah, there is work on it and the already game which has been shipped with, so I think it works.
Thank you.