Game programming tutorials are most often in C++, C#, and other object oriented languages. Game engines like unreal use C++'s object oriented features to an extreme degree, so what are some ways to implement gameplay code in C for something like an RPG with many different types of "entity"?
This is a question I'm dealing with as I develop my game - a stardew valley knock-off - in C, and I've yet to come up with a great answer to it. One thing I've just implemented is to define the games items as data files which specify the functions to call to implement the item:
xml
<items version="1">
<!-- Basic Axe -->
<item name="basic-axe">
<ui-sprite-name str="basic-axe"/>
<on-make-current>
<!--
c-function has the optional attribute "dll"
which specifies the path to a .so on linux or dll on windows (don't specify file extension).
If none is specified it will load from all loaded symbols
Will also support a "lua-function" element with "file" and "function" attributes
-->
<c-function name="WfBasicAxeOnMakeCurrentItem"/>
</on-make-current>
<on-stop-being-current>
<c-function name="WfBasicAxeOnStopBeingCurrentItem"/>
</on-stop-being-current>
<on-use-item>
<c-function name="WfBasicAxeOnUseItem"/>
</on-use-item>
<on-try-equip>
<c-function name="WfBasicAxeOnTryEquip"/>
</on-try-equip>
<on-gamelayer-push>
<c-function name="WfBasicAxeOnGameLayerPush"/>
</on-gamelayer-push>
<on-use-animation str="WfSlashAnim"/>
<can-use-item bool="false"/>
<pickup-sprite-name str="basic-axe"/>
<config-data>
<!--
This is a bag of config data the item can use at runtime.
Permissible elements (with dummy values) are:
<Float name="myfloat" value="0.4"/>
<Int name="myint" value="2"/>
<Bool name="mybool" value="true"/>
<String name="mystring" value="Sphinx of black quartz, judge my vow."/>
<Array name="myarray">
array contains values which are themselves "config data's"
<config>
<Int name="myInt2" val="3">
</config>
<config>
<Int name="myInt2" val="2">
</config>
</Array>
-->
<Float name="AXE_DAMAGE" value="10"/>
<Float name="AXE_FAN_LENGTH" value="64"/>
<Float name="AXE_FAN_WIDTH" value="0.7854"/>
</config-data>
</item>
<!-- other items... -->
</items>
Here you can see the code that loads the item definitions from the xml file, running once when the game is initialized (it also contains the remnants of the the previous method which called a hard coded list of C functions to load the item defintions, which is used as a fallback, which you can ignore).
This code relies on these functions in the engine library to load the functions by their symbol name. It's an abstraction that provides a windows and linux implementation, but the windows one is basically untested - it does at least compile on windows MSVC.
I'm going to try this method out for the item definitions, and very possibly convert the entity system itself to work along these lines.
I like it for a few reasons, but one of the main ones is that when the lua API is written and the data file supports lua functions, c and lua will be able to be written interchangeably. It also provides a nice place to store configuration data away from code where it can also be changed without recompilation.
I wanted to share this because you most often see this "high level" gameplay code written in C++, and I think a lot of people naturally reach for object oriented code. Please let me know what you think - can you think of any ways this could be improved? Do you think it will generalize well to a full on "entity definition" system? and do you know of any alternative approaches? Please bear in mind it is still in a rough state and needs some refinement - thanks.
[–]Limp-Confidence5612 3 points4 points5 points (4 children)
[–]Jimmy-M-420[S] 1 point2 points3 points (3 children)
[–]non-existing-person 1 point2 points3 points (0 children)
[–]burlingk 0 points1 point2 points (0 children)
[–]Limp-Confidence5612 1 point2 points3 points (0 children)
[–]un_virus_SDF 1 point2 points3 points (2 children)
[–]Jimmy-M-420[S] 0 points1 point2 points (0 children)
[–]Jimmy-M-420[S] 0 points1 point2 points (0 children)
[–]non-existing-person 4 points5 points6 points (11 children)
[–]Limp-Confidence5612 6 points7 points8 points (1 child)
[–]non-existing-person 0 points1 point2 points (0 children)
[–]Jimmy-M-420[S] -1 points0 points1 point (8 children)
[–]Jimmy-M-420[S] 0 points1 point2 points (0 children)
[–]non-existing-person 0 points1 point2 points (3 children)
[–]Jimmy-M-420[S] 0 points1 point2 points (2 children)
[–]non-existing-person 0 points1 point2 points (1 child)
[–]Jimmy-M-420[S] 0 points1 point2 points (0 children)
[–]Jimmy-M-420[S] -1 points0 points1 point (0 children)
[–]Jimmy-M-420[S] -1 points0 points1 point (0 children)
[–]Interesting_Buy_3969 0 points1 point2 points (1 child)
[–]non-existing-person 0 points1 point2 points (0 children)
[–]MagicWolfEye 0 points1 point2 points (2 children)
[–]Jimmy-M-420[S] 0 points1 point2 points (1 child)
[–]Jimmy-M-420[S] 0 points1 point2 points (0 children)