Hello, it's been awhile. I've been working on this for a while on and off, and I'm pretty sure I actually posted about this before, but there's been a stretch of a few months where I haven't been posting much, due to some personal problems, so I figured it would be best to post a new topic.
I'm in the process of writing a generic 2D RPG Engine in Python, mainly because I'm too cheap to get RPGMaker. So far I haven't built much beyond the map, though I'm pretty happy with what I've managed to accomplish there. Currently, the following things have been implemented:
the construction of arbitrary animated non-tiled maps
maps built dynamically, loaded from .dat files
objects on the map have associated animations, can have an effect when interacted with that can be turned on and off
portals can be open/closed, made to open in only a certain direction
a single text box which could appear for example when interacting with a sign or something which prints text at variable speed, or instantaneously.
screen size, file types for maps/sprites, settings for textbox (font size, txt/back color, text loading speed etc.) set in a .cfg file
'camera' focused on an arbitrary rectangle around the player. When the player moves outside the rectangle, the camera moves to follow them.
features which have been partially implemented:
a scripting language to handle cutscenes and some more advanced interactions.
effects which can be applied to objects or text during cutscenes, such as fade in/out, changing color etc.
features that are planned but not implemented:
transitions between maps (e.g. fade to black, then fade into new map)
sound
events triggering on menu load
chest-type objects
and of course, the other two thirds of the game, menus and battles.
Once things are more complete I'll post the source code if there is any interest. If anyone would like to see it now, I'd be happy to send it to them, but be warned that I am a self-taught programmer which no concept of best practice. global and exec await.
Speaking of which, I'm currently running into a problem with my scripting language. One of the things I would like for it to be able to do is to modify or print the value of game variables, most usefully for things like the player's name or to say how much gold the player needs to buy a bridge or something like that. It is entirely possible to cover each of these cases individually, but considering that I want to make a general purpose engine it is also really stupid and would then require the user memorize a few dozen commands, as well as preventing them from adding in their own variables (for example, if they want to add a randomized password to a door or something. Again, I could just make a bunch of dummy variables or something, but again, that would be stupid and require memorizing a bunch of extra commands). The solution I am currently attempting to implement involves using exec, as I can think of no other way to reasonably handle this.
The following is called by a 'getNextEvent' type function when the script says to print a particular variable's value to the textbox:
#'next' is a string the first two characters of which are a code which determines what is to be done with the remaining characters. This is executed when the first two characters are ':['
param = 'Error' # storage variable, and placeholder value
exec('global ' + next[2:]) # intended to load or create whatever the variable is.
exec('param = str(' + next[2:] + ')') # intended to set param equal to the variable's value cast as a string
txtbox.text = txtbox.text + param # adds the value of the variable as a string to the end of the function
for example, if the next command were ':[foo', and there were a variable 'foo' equal to seven, then it should execute:
global foo
param = str(foo)
txtbox.text = txtbox.text + param
and the result should be equivalent to
txtbox.text = txtbox.text + str(7)
In practice, the second 'exec' statement seems never to be called. There is no error of any kind, but param's value never is changed. The first exec may or may not be called, as since I am only checking the value of 'a' here it would assume global anyway. This problem has persisted even in what I believe is the above code's simplest incarnation, reproduced below:
a = 1
def b():
param = 'Error'
exec('global a')
exec('param = a')
print(param)
print(a)
b()
If anyone could explain why this is happening, or offer a workaround not using exec, it would be greatly appreciated.