![]() |
|
Data-driven game with Lua |
OnlineCop
Member #7,919
October 2006
![]() |
Is it better (I'm not saying easier; I'm saying better) to write a game engine so it's more data-driven (where the scripting language takes care of both defining and applying stats to an object), or split it between hard-coding the data types, and then modifying the (known) stats' values through the scripting language? 1enum eStats
2{
3 // Bad stats
4 STAT_POISON = (1 << 0),
5 STAT_SLEEP = (1 << 1),
6 STAT_BLIND = (1 << 2),
7 STAT_CURSED = (1 << 3),
8 STAT_ANTIMAGIC = (1 << 4),
9 STAT_SLOW = (1 << 5),
10 ...
11
12 // Good stats, helps counteract above bad stats
13 STAT_ANTIPOISON = (1 << 15),
14 STAT_ALERTNESS = (1 << 16),
15 STAT_VISION = (1 << 17),
16 STAT_BLESSED = (1 << 18),
17 STAT_FULLPOWER = (1 << 19),
18 STAT_SPEEDUP = (1 << 20),
19 ...
20};
21
22class Entity
23{
24 unsigned int hp, mhp;
25 unsigned int mp, mmp;
26
27 unsigned int stats; // bitfield using eStats above
28
29 ...
30
31public:
32 ...
33
34 unsigned int get_hp() { return hp; }
35 unsigned int get_mhp() { return mhp; }
36 unsigned int get_mp() { return mp; }
37 unsigned int get_mmp() { return mmp; }
38
39 void set_hp(unsigned int _hp) { if (_hp < mhp) hp = _hp; else hp = mhp; }
40 void set_mhp(unsigned int _mhp) { if (_mhp < 9999) mhp = _mhp; else mhp = 9999; }
41 void set_mp(unsigned int _mp) { if (_mp < mmp) mp = _mp; else mp = mmp; }
42 void set_mmp(unsigned int _mmp) { if (_mmp < 999) mmp = _mmp; else mmp = 999; }
43
44 unsigned int set_stat(unsigned int _stat) { stat = _stat; return stat; }
45
46 ...
47};
Here, all types of stats are defined in the eStats enumeration. If I wanted a new type of stat, I have to recompile my engine. Also, the values 9999 and 999 are hard-coded, and that would be a prime candidate to be moved into the script in case those values will be changed (or more validation is required). That part should be fairly easy to implement as script-driven, but what about the actual stats types? If I want to add a new stats type, could it be completely implemented in data?
|
Trezker
Member #1,739
December 2001
![]() |
I think it's a good idea to do more on the script side. Which stats you use and how they work is very much a game design area. This I think fits very well in scripting since it's something that will likely change a lot at the whim of a designer. |
Vanneto
Member #8,643
May 2007
|
I just cant help to notice: if (_hp < mhp) hp = _hp; else hp = mhp; Isn't it better to write this as: if (_hp <= mhp) hp = _hp; ? In capitalist America bank robs you. |
Fishcake
Member #8,704
June 2007
![]() |
Vanneto said: Isn't it better to write this as: if (_hp <= mhp) hp = _hp; This one does nothing if you pass in a value larger than mhp, while the original one will set hp to mhp.
|
Vanneto
Member #8,643
May 2007
|
Ah yes, how stupid of me. Thanks for clearing it up. In capitalist America bank robs you. |
Anomie
Member #9,403
January 2008
![]() |
I'd say that data-driven is better, but you have to find the domain of the data. Personally, I'm leaning toward a logic system based on components, where the engine only defines a base component class which is extended by subclasses written script-side. It's massively flexible, though hopefully not too difficult for me. To me, it makes the most sense to move everything you can out of the engine and into data. Performance-critical things like rendering and memory management would have to be handled internally, but gameplay logic and such are probably light enough to hold in data (especially in a relatively fast language like Lua). ______________ |
OnlineCop
Member #7,919
October 2006
![]() |
If I move everything to Lua (or any other scripting language for that matter), is it still data-driven? Or do I now just have a glorified script-based engine? Player movement, IMO, should be done in code, though where to move, and all the settings that affect it (speed, obstacle collision, etc.) can (and should) be done with the scripting language. Should that be correct?
|
Anomie
Member #9,403
January 2008
![]() |
OnlineCop said: If I move everything to Lua ... Obviously not everything, but anything that may change and isn't slow enough to require something faster. Quote: Should that be correct? So it looks like what you're wanting to do is just to manipulate variables (rather than define algorithms and logic) outside of the engine. Thinking back to when I first read articles about data-driven design, I suppose that's probably closer than what I suggest. Then again, I only ever heard the term used in the context of database systems and the like. The advantages are the same, it's just that in something like a game engine you generally need more flexibility than tweaking variables. If that's what you're looking for, I would suggest using config files rather than messing with Lua. ______________ |
Trezker
Member #1,739
December 2001
![]() |
I'm currently moving "everything" to Lua. At least interfaces to almost everything. I have bound allegro itself to Lua, followed by my 3D engine. In Lua I code all of the game and a even pieces that perhaps should be in C++. For instance the quadtree and collision code. Maybe this should be in C++ but so far performance of the program is good enough and I don't yet feel the need to optimize. |
Anomie
Member #9,403
January 2008
![]() |
Trezker said: For instance the quadtree and collision code. I'm impressed (and relieved) to hear that Lua can run all of that well, but what is your goal with transferring all that low level stuff into scripts? ______________ |
Trezker
Member #1,739
December 2001
![]() |
I'm not transferring it to scripts, I'm writing stuff in scripts first because I'm lazy. Then if it turns out it's too slow I transfer it to C++. I think it's much quicker to experiment with stuff in Lua than C++. It feels like writing pseudo code except I get real results. Then when I have a solid solution I can just convert it to C++. |
Audric
Member #907
January 2001
|
I can understand the interest of moving game logic outside of C sources, if it avoids expensive compilation+link time, but how does Lua fare in terms of error-checking ? Anyway, I thought the term 'data-driven' was rather related to things like a CRPG that would rely heavily on random generation: |
OnlineCop
Member #7,919
October 2006
![]() |
1a) Compile the LUA scripts into lua objects (LOB on my system) with `luac'. If there are errors, it will warn you where it was found. 1b) Makefiles are generally really good at detecting whether the LUA file is out of date and updating only necessary LOB files. 2) It will do that too, but a good rule of thumb is to check for a "nil" return result to your function calls. If you put in this syntax: x, y = get_coords("some_marker") and 'x' has a value but 'y' has 'nil', you have an error. Everything in a list like that are returned 'nil' if they are unspecified. 3) Yes, only when you load that line of code. It won't give you an error if you never run the bad code.
|
|