I'm trying to think of a good folder structure for the future of Flare.
What I'd like to have:
1. Easy translation support
Most likely: all english text is in an "en" folder, french text is in a "fr" folder, etc. Then the user can choose the displayed language via a simple config setting (default would be language=en). These should be separate from other game values. For example there should be one central items.txt with all the item stats, but a separate item_names.txt for each language.
2. Easy mod support
If a user wants to modify the core game, they can put files in a mods folder. The mods folder should probably mimic the file infrastructure of the core game data. When a mod is enabled, the engine should look for data files in the mod folder first, and in the core files second. So the mod folder can optionally override any game data, or easily add new game data. Some data can be additive, e.g. combine the core powers/items with the powers/items from a mod. If a mod uses the same item or power ID as a previous mod or core file, the last-defined item/power is used.
I'm not sure the best way to have multiple mods that don't conflict; maybe a mods.txt file that lists mods in preferred order?
So what I'm thinking for a basic structure (example): http://pastebin.com/y2JP2PLW
Thoughts?
Well, you shouldn't put all items and stuff in one big file, try to split them into multiple files and folders. For example like this:
http://pastebin.com/eVF7dQYU
Hm I don't know if that's practical. Wouldn't it make load times terrible to have to access that many tiny files? I'm talking about thousands of items and hundreds of powers, potentially.
Seems it would also be painful to edit. Let's say one person wants to go in and translate 1000 items. It's much easier to do that all in one file than to open, edit, save each file individually.
The speed advantage of having one big file instead of many small files shouldn't be that much. The advantages that you can find things much easier and that you can manage it more easily* are much more important than a second of loading time more.
Oh and... well yes, for translations central files are probably better.
*If you for example want to make a additional slightly modified sword you can just copy the folder, or if you want ro include an weapon from an other mod into your mod you can also simply copy its folder over. Or if you want to delete a power you can simply delete it's folder. (in contrast to search through the items.txt file, deleting that entry, searching through the image folder and remove the image for that power in there)
Thinking about this is hurting me head... But I do think to make things easier for potential translators the translateable words and sentences should all be one in place. A translator might not be easily able to grasp the directory structure if they are not interested in the development aspect of the project.
I think that having one large file each for powers and items is still the best way to do it. The way I envision both translations and mods is a supercession system.
Imagine this item, contained in core/items/items.txt:
[item]
id=563
name=Winter Shortbow
level=5
quality=high
type=off
icon=105,9
dmg=3,8
bonus=fire resist,6
power_mod=123
power_desc=Ice Ammo
req=o,3
sfx=wood
gfx=shortbow
loot=shortbow
price=28
It contains the whole item description.
Now, translations/fr/items/items.txt (I apologize for my Google Translation...):
[item]
id=563
name=Hiver Archet Court
power_desc=Munitions de Glace
Notice how it only contains the lines which supercede the original file? So first, the core/items/items.txt would be loaded. Then, the translations file (if applicable) would be loaded over the top of that one. Only the applicable values would be replaced. One advantage of this would be that a game can still be playable if only partially translated.
Now, let's say modders add some new items to items.txt. They place their file in mods/improved_armory/items/items.txt . This new file is loaded entirely instead of core/items/items.txt and blocks the loading of translations/fr/items/items.txt . If the mod also has a translations folder, it will load that in the same way it would have loaded the normal translation file.
Last notes:
To take care of internal strings in the flare-engine, there needs to be a separate external file containing them. I suggest core/messages/messages.txt as the name of the file. Then there would be a languages/fr/messages/messages.txt file as well.
Also, it may still be better for there to be a translations/en/ folder. That way it would be simple to copy/paste the directory structure, and all that's left to do would be translate the whole thing. On the other hand, the English portions of the files are often self-documenting (how would you know it was a Winter Shortbow unless you saw the name line?) and it may be worth it to leave those in the core files.
A possible way to do it is to treat the core files as just another mod. Hm...
/mods/fantasycore/
would contain all the current game data.
/mods/index.txt
would list "fantasycore" as the first mod to load. Then it would be quite easy for someone to do a full conversion, as the core is easily extracted.
It would also simplify the code if the core files weren't treated as special cases.
While possibly not the best solution, it certainly does simplify the development and programming process if you consider a "translation" to be a total conversion mod of the game. That way you could simply copy the whole game over and translate the files.
Hmm... the more I think about it, the more I like that idea. Mods and translations are the same thing.
You will want to add a 'mod' field to the save file, though, so you don't have weird effects by loading different mods.
Hm, let me think about that too. Seems sensible. Translations are a very narrow kind of mod anyway (overwrite text only, in most situations). It would certianly make sense to have the engine treat all mods the same way.
It seems as if there are two types of mods we may be talking about. First there are full games or total conversions, and second there are localized overrides. It's probable that both will eventually be wanted.
For example, if someone likes the full 'fantasycore' game, but only wants to create a new set of weapons, then it is certainly more efficient to have a new items.txt file override the old one.
http://pastebin.com/5b2YYKGC
Just a thought. Naturally, the problem with this is that it duplicates a lot of data. The advantage, on the other hand, is its ease in creating a new game/mod.
It'll probably make sense if mod files completely supercede files from previous mods. So, when opening any data file, look at the bottom of the mod list first. If the file isn't there look at the mod before it. Keep going until the first (core) mod.
Those local overrides can simply be mods too, I think. They can be small mods of only 1 file if necessary.
It could make translation simpler to have e.g. translation files only contain names/descriptions of items and powers; in other words, allow mods to alter parts of files. But those are the easiest-to-translate parts anyway. It'd be harder to separate the translations for events (NPC dialog and map events) because those don't use IDs (those would be harder to work with if unique IDs were necessary).
Anyway. We can always make it better later. Let's plan on this, as part of the v0.15 work required for Translations anyway.
Then if we get to the point where that's holding us back, we can look at allowing mods to change or add data within specific files, instead of completely overriding them.
/mod/fantasycore/ would have all the current sounds/images along with all the current game data files.
/mod/fantasycore_fr/ would probably only have .txt files, maybe some french voice-over files and a translated title screen image.
Then if they wanted fancy weapons they could have /mod/weaponpack/ (or maybe a french version if one exists)
> A possible way to do it is to treat the core files as just another mod.
Nice idea, like it. It will be also a good sample by itself about how to create mods.
One more things to consider:
- usually game engine and mod are developed by different teams and have it's own independent source control systems.
- it should be easy to update game engine to the new version (like 'git checkout master').
So - maybe mods shouldn't be placed inside of game engine folder (it will cause problems with for example 'git checkout master' command).
One way to solve this - add paths to mods to config:
[mods]
/path_to_mod_a/mod_a
/path_to_mod_b/mod_b
As a result - the game engine will have it's own folder and version control and each of mods will have the same, and it's easy to udate any of it
(and if You wish it still can be placed inside of game engine folders).
About the performance - with lots of mods there will be lot's of file checks. But I doubt if it will impact performance,
actually, the Ruby (Ruby on Rails) dependency system works exactly the same way, there are 'mods' (called gems) and a set of ordered resource paths, and it seems there's no any
performance problem (usually there's about 10-30 gems per project).
And even if it will cause performance problems, it can be solved as follows:
- first time game loads it creates the 'resource_paths_cache.txt' (resource_name: /path_to_resource) file with all resolved paths.
- next time it just reads from it.
- if the list of mods is updated (game config is never than resource_paths_cache) - recreate it.
I have got some thoughts about modding support in flare. For this article I use two mods.
Core, which is the basic flare game
Red World, which is a user made mod. In this mod, the goblins do not have a green skin but a red one.
Directories
The most simple solution is using directories for mods.
/usr/share/games/flare/core/
/usr/share/games/flare/red world/
…
Advantages
This is a working mod implementation, without needing to code a lot.
Disadvantages
It is not very data-friendly.
Mod Inheritance
I suppose that you are familiar with inheritance. If not, you can have a look at wikipedia, but remember it is quite technical. I suggest a similar approach with mods. Suppose that we say, 'red world' is a sub-mod of 'core'. If we look for a resource and it is not in the sub-mod it will look in it's parent mod.
If flare searches for minotaur.png it will first try:
/usr/share/games/flare/red world/monsters/minotaur.png
Not suprisingly, it will not find it there, so it will look in its parents mod 'core':
/usr/share/games/flare/core/monsters/minotaur.png
Advantages
It is easy to change an existing mod.
Disadvantages
Mods can have only one successor. This will probably be good enough in most cases.
In some cases, things are added in the parent mod with the same name as a resource in the clients mod. In this case you'll get problems. This could be solved to specify at each resource if it is a new resource or an overwritten one.
Other considerations
Namespaces
Sometimes it might be better to be able to directly name the mod where a resource can be found. In this case you could write something like.
core::minotaur.png
instead of
minotaur.png
Dependencies
It should be checked if the parent mod required by the mod is available. Otherwise it should give an error message. It would be nice if a link could be provided where you can download it.
Another consideration, is storing version numbers of mods.
Mod distribution
The easiest way to distribute a mod is in a .zip file (or any other compression method).
Maybe there should be a wiki article with a list of mods.
Multiple mods
One thing that is surely fun, is running several mods simultaneously. However there are new opportunities for conflicting files. The easiest way to solve this is ranking all mods in importance.
Override and / or new keywords
If red-world and core have both an item 397, you can have two situations.
We could let the program guess, but if we require the program to give the keyword override when we want to override, and otherwise take a new one, we will avoid a lot of wrongly handled conflicts.