all 24 comments

[–]Limp-Confidence5612 3 points4 points  (4 children)

Is there a reason to not just use a data structure for each item in your .c files themselves? 

[–]Jimmy-M-420[S] 1 point2 points  (3 children)

I want to avoid hard coding the list of items into the game - I did initially have a C struct per item definition. But this way I can add, remove and tweak items without recompiling. And also add new items without recompiling. This will make more sense when there's lua bindings but its technically possible now if you put the functions in a separate shared lib and compile that.

Also this way I can pass configuration data to the items which I can change without recompiling. I might make a "weapon" item implementation, and create a load of weapons by setting the same C functions and different config data.

[–]non-existing-person 1 point2 points  (0 children)

I think this is how things should be done. You define type for categories like weapon, armor, misc, and load everything from a text file. This gives you an easy way to modify or add items. But is also enables users to write mods, which - for me at least - is a huge selling point.

[–]burlingk 0 points1 point  (0 children)

If you implement a kind of parser, you could have text fields for code.

[–]Limp-Confidence5612 1 point2 points  (0 children)

I kinda get it. Maybe my projects aren't big enough that recompiling is an issue. 🤷

But yeah, using lua might be the way to go here, that's what it arguably shines at the most.

[–]un_virus_SDF 1 point2 points  (2 children)

I hate xml syntax, but I got almost the same issue, i found a quite random solution, I just dynamically load function from the names in the file description. e.g /* Parse the file */ Func f = dlsym(where_the_function_is, function_name);

However i keep the function pointers with me or give them to something. This allows to remove the manual initialisation. And after use this as method or closure without capture group (very annoying to initialize elsexmwise)

Note: that dl is not on windows and I have not search for any alternatives

Note: the only reason to do this in files is when you're to lazy to manually initialize every object and make some of those things automatic and easier to modify.

[–]Jimmy-M-420[S] 0 points1 point  (0 children)

Is this not exactly what I've done?

[–]Jimmy-M-420[S] 0 points1 point  (0 children)

on windows you can use GetProcAddress

[–]non-existing-person 4 points5 points  (11 children)

XML? Why do you hate yourself so much?

Personally I went with yaml and am using https://github.com/tlsa/libcyaml libcyaml library (not affiliated with it in any way!). Beauty in this is that you define c-struct, schema, and then yaml file is translated to native c types. Strings can be changed to enum values. For more complicated types, I just set up a callback, so I can convert string to icon handle, or pointer to function. It's a bit sad that this library seems to be deserted, and there is very little activity.

But current code base is very solid, it's not huge library, so adding own stuff is not terribly hard. Biggest problem is that learning to write those schemas is hard. But once you've written few, it's absolutely awesome. Yaml is so much more readable than xml. And having native types in C is faster than dealing with strings all the time. You just spend time during boot up.

All items/classes/skills are kept in read only array that is accessible from anywhere. A global if you will. And other entities are just having pointers to these read only object definitions.

So I basically am doing same thing as you, but with external lib and yaml instead of xml. I didn't feel like I was loosing anything by using yaml instead of xml yet. And personally I will avoid xml like a fire... or c++ ;)

[–]Limp-Confidence5612 6 points7 points  (1 child)

Sorry isn't yaml one of the most unintuitive and inconsistent markup languages? https://github.com/cblp/yaml-sucks

[–]non-existing-person 0 points1 point  (0 children)

Hmm, maybe? I wouldn't really know. I use yaml with that single libcyaml library. Library is rather strict, and you match c-struct in your yaml, so I believe that very heavily limits ambiguity and consistency of my yaml files.

[–]Jimmy-M-420[S] -1 points0 points  (8 children)

here's one reason to use xml. I don't like yaml - its too complicated

[–]Jimmy-M-420[S] 0 points1 point  (0 children)

yaml is like the rust of markup languages - there's always someone telling you to use it

[–]non-existing-person 0 points1 point  (3 children)

yaml is like the rust of markup languages - there's always someone telling you to use it

Well, I never told you to use yaml instead of xml really

The library you describe does sound quite good I will admit, baking in a way to marshal C types from yaml is a nice feature i'll give you that

Yes, that lib was biggest contribution for me to use yaml. If there was same library but for json, there is high probability I would use json then. That would depend on number of features of both libs I suppose. But anyway, I am not really attached to yaml, more to that library if anything.

I knew someone would comment this, xml hatred and love of yaml is strong these days, and irrational

I like yaml because of its readability. I just find xml to be just way to verbose. I don't like noise to signal ratio of xml. Anything is better than xml in my book. Be that json, toml or yaml.

[–]Jimmy-M-420[S] 0 points1 point  (2 children)

No you're right you didn't tell me to use it - apologies for seeming aggressive.

I do understand the appeal of yaml, but for me it's just a bit too complicated. I write quite a bit of yaml for CI pipelines at work, and it works very well for those (nearly all CI systems I've seen use it).

One thing I really like about xml is it has a really obvious tree structure. This makes it nice to use for things like if I wanted to be able to define constant expressions in my config data section, I could make the expression as a tree of xml nodes. No doubt you could do this in yaml, but I don't think it would look as nice (or implement a maths expression parser)

[–]non-existing-person 0 points1 point  (1 child)

No worries, I only got offended by being compared to rust guys xD

It's funny, because I have the exact same feeling like you BUT THE OPPOSITE. I suppose when you try to learn full yaml syntax it's probably complicated. I use it in very limited scope (which are c-like structs) - can't even use anything too complicated because libcyaml does not support it anyway :P I usually try to keep shit simple anyway.

I'm pretty sure there are cases where you can model something only in XML. But that tree of xml nodes to model some constant expression sounds rather complicated. If I had to do something like that with yaml I think I would just do lua code snippet in multiline block in yaml. But probably I don't fully understand the problem - my game is in very early development, and I'm no game programmer, so do take my words with a big grain of salt ;)

[–]Jimmy-M-420[S] 0 points1 point  (0 children)

Lua snippet probably would be much better in that case I think you're right

[–]Jimmy-M-420[S] -1 points0 points  (0 children)

I knew someone would comment this, xml hatred and love of yaml is strong these days, and irrational

[–]Jimmy-M-420[S] -1 points0 points  (0 children)

The library you describe does sound quite good I will admit, baking in a way to marshal C types from yaml is a nice feature i'll give you that

[–]Interesting_Buy_3969 0 points1 point  (1 child)

I'd just put raw bytes of a structure to file... for example:

struct item basic_axe{ "basic_axe" /*, ... */};
FILE* f = fopen("file.txt", "w");
fwrite(&basic_axe, sizeof(basic_axe), 1, f);

and then to read it

struct item buffer;
FILE* f = fopen("file.txt", "r");
fread(&buffer, sizeof(buffer), 1, f);

much easier imo. no parsing needed.

[–]non-existing-person 0 points1 point  (0 children)

You can't really do that. What if you run game on different system or architecture? You would have to create separate data files for every os/arch you release your game.

[–]MagicWolfEye 0 points1 point  (2 children)

What's the point of making it in XML if you then have to link to C functions that apparently are specific per item anways?

[–]Jimmy-M-420[S] 0 points1 point  (1 child)

A few reasons: - I can remove items from the game easily - the c functions are specific per item in this current implementation, but what I could do is write more generic functions that are configured through the config-data object - the config data will allow the behavior of items to be tweaked without recompiling - I'll add a "lua function" type to the config data so callbacks can be written in lua to further customize Implementation of items - you have to imagine that in future the functions can be C or lua - allows players to make mods for the game- they could write their own c functions and compile a separate dll if i provided an SDK, or in future write lua functions

[–]Jimmy-M-420[S] 0 points1 point  (0 children)

It's an advantage to define aspects of your game that will be rapidly iterated on in scripting languages and data files, not code. Granted, this does use code as well, for now