Jump to content
Site Stability Read more... ×
  • Advertisement
Sign in to follow this  
Saif Punk

Is Python any good for...?

This topic is 2042 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey there,

First of all, i'm sorry if it's wrong forum
since i couldn't find General Dicussion forum(maybe GameDev don't have)
and again i'm sorry.

I would like to know is Python good for
game scripting? let's say » i've a 3D game engine which is C++ programming and Python scripting.

Is it any good? I know lots of people says Lua is better with C++ but i would like to give python a try.

My questions is whats wrong with python?
I know Python is bad at calculating but i can use C++ when i need calculation.(Correct me if i'm wrong.)

Python vs Lua « which one faster?

Is Python good scripting language?

Why will someone choose Python scripting?

Good stuff about Python scripting?

Thank you.

SaiF PUNK

Share this post


Link to post
Share on other sites
Advertisement

Well, having just made an app that use both lua and python from c++ code, i have to say that Lua imo is way easier to interface with c++.

 

Having said that, python is, imo, a much more powerfull scripting language, with more built-in functionality than lua, for example, strings manipulation, math stuffs ect. Since im no expert in either of those scripting languages, i can't really tell you more than that.

 

To give you an idea of what im talking about, look at my Lua interface code

#include "LuaScript.h"

CLuaScript::CLuaScript()
{
	L = NULL;
	InitLua();
}

CLuaScript::~CLuaScript()
{
	CloseLua();
}

void CLuaScript::InitLua()
{
	if(!L){
		L = lua_open();
		luaL_openlibs(L);
	}
}

void CLuaScript::CloseLua()
{
	if(L){
		lua_close(L);
		L = NULL;
	}
}

void CLuaScript::ResetLua()
{
	CloseLua();
	InitLua();
}

bool CLuaScript::LoadScriptFromFile(string scriptfile)
{
	ResetLua();

	bool value = true;

	try {
		luaL_dofile(L, scriptfile.c_str());
	} catch(...) {
		value = false;
	}

	return value;
}

bool CLuaScript::LoadScriptFromText(string scripttext)
{
	ResetLua();

	bool value = true;

	try {
		luaL_dostring(L, scripttext.c_str());
	} catch(...) {
		value = false;
	}

	return value;
}

void CLuaScript::CallFunction(string name)
{
	//call script function, 0 args, 0 retvals
	lua_getglobal(L, name.c_str());
	lua_call(L, 0, 0);
}

bool CLuaScript::SafeCallFunction(string name, char *err)
{
	//call script function, 0 args, 0 retvals
	lua_getglobal(L, name.c_str());
	int res = lua_pcall(L, 0, 0, 0);

	if(res > 0){
		const char *pErrMsg = lua_tostring(L, 1);

		if(!err){
			string Caption;
			Caption = "Lua: Error in function " + name + "().";

			MessageBox(0, pErrMsg, Caption.c_str(), MB_OK);
		} else {
			sprintf(err, "%s", pErrMsg);
		}

		return false;
	}

	return true;
}

string CLuaScript::GetGlobalString(string name)
{
	string value = "";
	try {
		lua_getglobal(L, name.c_str());
		const char *pValue = lua_tostring(L, -1);
		if(pValue)
			value = pValue;
		lua_pop(L, 1);
	} catch(...) {
	
	}

	return value;
}

void CLuaScript::SetGlobalString(string name, string value)
{
	lua_pushstring(L, value.c_str());
	lua_setglobal(L, name.c_str());
}

double CLuaScript::GetGlobalNumber(string name)
{
	double value = 0.0;
	
	try {
		lua_getglobal(L, name.c_str());
		value = lua_tonumber(L, -1);
		lua_pop(L, 1);
	} catch(...) {
	
	}

	return value;
}

void CLuaScript::SetGlobalNumber(string name, double value)
{
	lua_pushnumber(L, (int)value);
	lua_setglobal(L, name.c_str());
}

bool CLuaScript::GetGlobalBoolean(string name)
{
	bool value = false;
	
	try {
		lua_getglobal(L, name.c_str());
		value = lua_toboolean(L, -1) != 0;
		lua_pop(L, 1);
	} catch(...) {
	
	}
	
	return value;
}

void CLuaScript::SetGlobalBoolean(string name, bool value)
{
	lua_pushboolean(L, (int)value);
	lua_setglobal(L, name.c_str());
}


Clean and simple, most likely bugless, now look at the same thing for python

#include "PythonScript.h"

CPythonScript::CPythonScript()
{
	Initialized = false;
	InitPython();
}

CPythonScript::~CPythonScript()
{
	ClosePython();	
}

void CPythonScript::InitPython()
{
	if(!Initialized){
		Py_Initialize();
		module = PyImport_AddModule("__main__");
		dictionary = PyModule_GetDict(module); 
		Initialized = true;
	}
}

void CPythonScript::ClosePython()
{
	if(Initialized){
		Py_Finalize();
		module = dictionary = NULL;
		Initialized = false;
	}
}

void CPythonScript::ResetPython()
{
	ClosePython();
	InitPython();
}

bool CPythonScript::LoadScriptFromFile(string scriptfile)
{
	ResetPython();

	try {
		FILE *f = fopen(scriptfile.c_str(), "rt");
		if(f){
			PyRun_File(f, scriptfile.c_str(), Py_file_input, dictionary, dictionary);
			fclose(f);
		}
	} catch(...) {
		return false;
	}

	return true;
}

bool CPythonScript::LoadScriptFromText(string scripttext)
{
	ResetPython();

	try {
		PyRun_String(scripttext.c_str(), Py_file_input, dictionary, dictionary);
	} catch(...) {
		return false;
	}

	return true;
}

void CPythonScript::CallFunction(string name)
{
	//call script function, 0 args, 0 retvals
	PyObject* pFunc = PyObject_GetAttrString(module, name.c_str());
	PyObject_CallObject(pFunc, 0);
	//Py_DECREF(pFunc);
}

bool CPythonScript::SafeCallFunction(string name, char *err)
{
	//call script function, 0 args, 0 retvals
	PyObject* pFunc = PyObject_GetAttrString(module, name.c_str());
	if(pFunc){
		PyObject_CallObject(pFunc, 0);
		Py_DECREF(pFunc);
	}

	int have_error = PyErr_Occurred() ? 1 : 0;
	
	if(have_error){

		//const char *pErrMsg = getPythonTraceback();

		if(!err){
			string Caption;
			Caption = "Python: Error in function " + name + "().";

			//MessageBox(0, pErrMsg, Caption.c_str(), MB_OK);
		} else {
			sprintf(err, "Python: Error in function %s().", name.c_str());
		}

		return false;
	}

	return true;
}

string CPythonScript::GetGlobalString(string name)
{
	string value = "";

	PyObject* s = PyDict_GetItemString(dictionary, name.c_str());
	if(s){
		PyObject *s_Ansi = PyUnicode_AsEncodedString(s, "utf-8", "");
		const char *pValue = PyBytes_AS_STRING(s_Ansi);
		Py_DECREF(s);
		if(pValue)
			value = pValue;
	}

	return value;
}

void CPythonScript::SetGlobalString(string name, string value)
{
	PyObject *s = PyUnicode_FromString(value.c_str());
	if(s){
		PyDict_SetItemString(dictionary, name.c_str(), s);
		Py_XDECREF(s);
	}
}

/*double CPythonScript::GetGlobalNumber(string name)
{
	double value = 0.0;
	
	try {
		lua_getglobal(L, name.c_str());
		value = lua_tonumber(L, -1);
		lua_pop(L, 1);
	} catch(...) {
	
	}

	return value;
}

void CPythonScript::SetGlobalNumber(string name, double value)
{
	lua_pushnumber(L, (int)value);
	lua_setglobal(L, name.c_str());
}

bool CPythonScript::GetGlobalBoolean(string name)
{
	bool value = false;
	
	try {
		lua_getglobal(L, name.c_str());
		value = lua_toboolean(L, -1) != 0;
		lua_pop(L, 1);
	} catch(...) {
	
	}
	
	return value;
}

void CPythonScript::SetGlobalBoolean(string name, bool value)
{
	lua_pushboolean(L, (int)value);
	lua_setglobal(L, name.c_str());
}*/

/*char* getPythonTraceback()
{
    PyObject *type, *value, *traceback;
    PyObject *tracebackModule;
    char *chrRetval;

    PyErr_Fetch(&type, &value, &traceback);

    tracebackModule = PyImport_ImportModule("traceback");
    if (tracebackModule != NULL)
    {
        PyObject *tbList, *emptyString, *strRetval;

        tbList = PyObject_CallMethod(tracebackModule, "format_exception", "OOO", type, value == NULL ? Py_None : value, traceback == NULL ? Py_None : traceback);

        emptyString = PyUnicode_FromString("");
        strRetval = PyObject_CallMethod(emptyString, "join", "O", tbList);

		PyObject *strRetval_Ansi = PyUnicode_AsEncodedString(strRetval, "utf-8", "");
		chrRetval = strdup(PyBytes_AS_STRING(strRetval));
        //chrRetval = strdup(PyString_AsString(strRetval));

        //Py_DECREF(tbList);
        //Py_DECREF(emptyString);
        //Py_DECREF(strRetval);
        //Py_DECREF(tracebackModule);
    } else {
        chrRetval = strdup("Unable to import traceback module.");
    }

    //Py_DECREF(type);
    //Py_XDECREF(value);
    //Py_XDECREF(traceback);

    return chrRetval;
}*/


I pretty sure they might be bug in this last snippets(its a work in progress), but it works. Python is more complex to interface, but it's also more powerfull imo compared to lua.

 

Here's a script i wrote to generate a filename with 16 randoms characters, and keep the extention intact in lua

ScriptName = "Random"
InitialDirectory = ""

Input = ""
Output = ""

--------------------------------------------------------------------------------------------------------------------
-- Return the char at positon i in s
--------------------------------------------------------------------------------------------------------------------
function GetChar(s, i)
	return string.sub(s, i, i)
end

--------------------------------------------------------------------------------------------------------------------
-- Concat. 2 strings together
--------------------------------------------------------------------------------------------------------------------
function ConcatStr(s1, s2)
	return string.format("%s%s", s1, s2)
end

--------------------------------------------------------------------------------------------------------------------
-- Return the extention of a given file name
--------------------------------------------------------------------------------------------------------------------
function GetExtention(s)
	local sLen = string.len(s)

	local found = false
	local tmp = ""
	local i = sLen
	local j = 0
	while(i > 1) do
		tmp = ""
		tmp = string.sub(s, i, i)
		if(tmp == ".") then
			found = true
			break
		end
		i = i - 1;
	end;

	tmp = ""
	if(found == true) then
		while(i <= sLen) do
			tmp = tmp..string.sub(s, i, i)
			i = i + 1;
		end;
	end;

	return tmp
end


--------------------------------------------------------------------------------------------------------------------
-- Convert the file name (Called from c++)
--------------------------------------------------------------------------------------------------------------------
function Convert(FileName)
	local FileName = Input
	Output = ""

	-- Extract the file extention
	local ext = GetExtention(FileName)

	local tmp = ""
	local i = 1;
	local r = 0
	local c = ""

	while(i <= 16) do

		local k = math.random(2)
		if(k == 1) then
			r = math.random(65,90)
			c = string.char(r)
			tmp = string.format("%s%s", tmp, c)
		end
		if(k == 2) then
			r = math.random(48,57)
			c = string.char(r)
			tmp = string.format("%s%s", tmp, c)
		end

		i = i + 1
	end

	Output = string.format("%s%s", tmp, ext)

	print(Output)
end

math.randomseed(os.time())

Now, look how simple it is to do the same in python

import random, os.path

ScriptName = "Random"
InitialDirectory = ""

Input  = "Sample.avi"
Output = ""

##-------------------------------------------------------------------------------------------------------------------
##- Generate a random character
##-------------------------------------------------------------------------------------------------------------------
def GenRandChar():
    r = random.randrange(0,1)
    
    s = ""
    if(r == 0):
        s = chr(random.randrange(65, 65 + 26))
    elif(r == 1):
        s = chr(random.randrange(48, 48 + 10))

    return s

##-------------------------------------------------------------------------------------------------------------------
##- Convert the file name (Called from c++)
##-------------------------------------------------------------------------------------------------------------------
def Convert():
    global Input
    global Output
    
    FileName = ""

    for i in range(16):
        FileName = FileName + GenRandChar()

    FileExt = os.path.splitext(Input)[1]
    
    Output = FileName + FileExt



So, with that in mind, ill let you draw you're own conclusion. And for the speed question, of course a compiled language will always be faster than a scripted one, but for lua vs python, i guess you'd have to make some benchmarks.

Edited by Vortez

Share this post


Link to post
Share on other sites

I would like to know is Python good for
game scripting?

Well, you could use it. Python is however a language with a lot of libraries and AFAIK a relatively big standard library. You won't need most of these things as you will probably just interface with your C++ code and define simple mechanics.

I know lots of people says Lua is better with C++ but i would like to give python a try.

That's probably because Lua was made to be embedded inside your application. There are a lot of wrappers out there, also very easy-to-use ones. Python is not used for embedding this much. It's also slower (compared to LuaJIT, I don't know about the regular Lua interpreter).

I know Python is bad at calculating but i can use C++ when i need calculation.(Correct me if i'm wrong.)

A scripting language will practically always be slower than a compiled language. But you can indeed do the heavy calculations inside your C++ code.

Python vs Lua « which one faster?

As I already mentioned, LuaJIT is faster than Python. There are multiple reasons for this. For example because Lua is a simpler language (so also faster to learn). But also because Lua was so simple it was relatively easy to use JIT-compiling (compile the Lua code into assembly on run-time). When you use something like LuaJIT the calls to C++ will be the slowest. I don't know how Python handles this, but it could be slower because Python was not made to be embedded.

Is Python good scripting language?

Python is a "good" scripting language. The amount of users prove that. For an embedded scripting language, it is however slower to learn than e.g. Lua in my opinion. But it has a big community and many libraries which you may or may not need in your logic code.

 

I can't answer the other two questions because I don't have much experience with Python.

Share this post


Link to post
Share on other sites

Hey there,

First of all, i'm sorry if it's wrong forum
since i couldn't find General Dicussion forum(maybe GameDev don't have)
and again i'm sorry.

I would like to know is Python good for
game scripting? let's say » i've a 3D game engine which is C++ programming and Python scripting.

Is it any good? I know lots of people says Lua is better with C++ but i would like to give python a try.

My questions is whats wrong with python?
I know Python is bad at calculating but i can use C++ when i need calculation.(Correct me if i'm wrong.)

Python vs Lua « which one faster?

Is Python good scripting language?

Why will someone choose Python scripting?

Good stuff about Python scripting?

Thank you.

SaiF PUNK

 

I don't have much experience with Lua but I have a lot of experience with python and I love it. Having said that, I would not consider using python as a scripting language that I would call from within C++. For that, I think Lua is a better fit or even javascript. I would, however, consider calling C++ from python and I think that would be a great fit.

 

I would not say that python is particularly slow for computation (for an interpreted language) and there are plenty of easy ways to accelerate it (although they all involve delegating the computation to C in one way or another).

 

-Josh

Share this post


Link to post
Share on other sites

Thank you guys.

 

one question, how will this fit a game engine.

 

Programming language: C++

Scripting language: C++

Graphic API: DirectX

Physics Library: Not sure.

 

Thank you.

SaiF PUNK

Edited by SaiF PUNK

Share this post


Link to post
Share on other sites


Scripting language: C++

 

C++ is not a scripting language, at least last time i checked :)

Share this post


Link to post
Share on other sites
Well, C++11 is scripting language and programming language.

Epic games have C++ scripting language in Unreal Engine 4.

Share this post


Link to post
Share on other sites

The terms scripting language and programming languages really only differ in how the languages are being used -- all scripting languages are programming languages, and any programming language could potentially be used as a scripting language.  So yes, you can use C++ (11 or otherwise) as a scripting language, and there are at least a couple of cases in which it has been done.

 

 

That being said, C++ is not typically used as a scripting language, and without modification it lacks a couple of the features commonly looked for in a scripting language.

 

 

Use whatever meets the needs of your project and works best for you.  My instinct would be that C++ probably isn't the best choice as a scripting language (I would prefer Lua, or if you want something more similar to C++ perhaps AngelScript), but if you feel differently you absolutely can proceed, and it may well work out best for you.

 

 

Hope that helps! smile.png

Share this post


Link to post
Share on other sites
Thank you jbadams.

One last question.

Is it possible to have a game engine without scripting language and add scripting language later on?

and is it possible to change scripting language from xxx to xxx?

I think it's possible but i need someone to confirm this.

Thanks

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!