SFTtech / openage

Free (as in freedom) open source clone of the Age of Empires II engine 🚀
http://openage.dev
Other
12.63k stars 1.11k forks source link

Asset pack format #632

Closed TheJJ closed 3 years ago

TheJJ commented 7 years ago

We need a convention on how a asset pack looks like.

Q: What is an asset pack? A: A collection of files that provide the engine with data to display.

Q: What is in an asset pack? A: Some files, proposal:

example mod pack:

    only enforced file name: pack.nfo
    /
        pack.nfo <- "load = anothermod.nyan; mod = anothermod.MonsterMod"
        anothermod.nyan <- "import tentaclemonster.monster; MonsterMod(Mod)..."
        tentaclemonster/
            monster.nyan
            moving.png
            raping.png
            fleeing.png
            rape.py <- when a mod registers >=1 py file, it's a "code mod" that displays a big red ! if not signed by openage-authors.

nfo format idea:

name: (identifier) (must equal folder name?) (identifier in oa mod repository)
version: (major.minor.patch)

provides: (list of [identifier (= version)]))
conflicts: (list of [identifiers ((>=, <=) version)])
requires: (list of [identifiers ((>=, <=) version)])

description: <human-readable>
url: <mod homepage>
license: (license name or url or whatever)
authors: username <mail>, anotherguy <moremail>

load: folder/somedata.nyan
mod: folder.somedata.ModObject

examples and further ideas:

vanilla/pack.cfg:

name: vanilla
version: 1.0.0
provides: base
conflicts: sftflavouredvanilla
description: converted from AoC by openage alpha 1.2.3
url: http://openage.sft.mx
license: proprietary
authors: ensemble studios (via openage.convert)

load: data/main.nyan
mod: data.main.Main

villageroverhaul/pack.cfg:

modname: villageroverhaul
version: 4.2
requires: base   # you could also write 'requires: vanilla'.
description: makes your villager so much better you'll never want to play stock oa again!
url: http://forum.openage.sft.mx/mods/villager_overhaul

load: villager/mod.nyan
mod: villager.mod.BetterVillager

== not part of this task, just for your understanding: == When the mod is enabled, the whole mod pack will be mounted as /$modname/{contents_of_the_pack}.

Afterwards, the .nyan file denoted to load in pack.nfo is parsed (which will then read all imported other .nyan files), loaded and checked for errors.

Then, the mod is activated by applying all the patches denoted in the Mod object referenced in the metadata file. This will actually initially modify the game data tree and "install" the mod. == end of just-to-understand section ==


Basically, please design and implement the above in openage/pack/ so that we have a Python class Pack we can create for a mod pack like somemod = Pack("path/to/the/mod/pack/").

Then somemod.name returns the name, somemod.patches returns the name of the nyan patches, and so on.

edit: use .nfo instead of .oam :)

These packs are then loaded and managed by the mod loader.

timo-42 commented 7 years ago

Information files should have the file extension: .nfo (mod.nfo)

mic-e commented 7 years ago

:+1: bonus points if .nfo files are formatted as ASCII art

castilma commented 7 years ago

Maybe this should be mentioned here: https://pad.stusta.mhn.de/p/openage-modformat

timo-42 commented 7 years ago

We should track Mod/Asset archive file with a hash function(e.g. SHA-3). So nobody confuses packs. Modder may update them and forget the version bump while testing. Maybe this leads to unnecessary problems at network games.

And if we use them, there can be multiple untrusted mirrors where Modfiles and maps are hosted. So it doesnt matter where you get the archives from, everyone can check if they have the same files for games.

requires, depenency,.. list of SHA-3 hashes

new field: updates: SHA-3 (hash of the old mod package) (so we can track files, maybe delete old packs on disk to save space)

we should also consider a map format. Maps may only be userfull for/with certain mods(CBA).

proposal:

path info
/assets/ Content Cell
/assets/audio/ special audio files
/assets/pictures/ prev_XXX.png used for displaying map preview ingame and on the website
/type.nfo determinates what type of archive this is(single string: map,mod,assets,...)
/map.rms (if random map script)
/map.info metadata for the map (name,author,version,minPlayer,maxPlayer,maxTeams,gameTypes=standard,conquest,kingofthehill,...description) and important: which map creation engine to use(random map engine, single scenario, unlimited map?..)
TheJJ commented 7 years ago

Good idea with the hash verification, but i'd not store the hashes but just verify those on the clients if the same mod was loaded.

I would not force the folder layout and just require on index file name. That way, mods can organize themselves in any way they like. Also, your scheme would restrict the mod to only add one randommap.

Also, I wouldn't say there is any need to specify a type of the mod because all are the same, even the one generated by the convert script.

timo-42 commented 7 years ago

Oh, there is a misunderstanding: The only thing I want to enforce is the type.info. This File will determinate the rest of the structure. Yes, this is my proposal for random map layout.

TheJJ commented 7 years ago

I understand, but still i don't see the reason we even need archive types and a fixed structure, even for random maps. You can add some folder called maps, and add a nyan file describing all of them. This also means there is no map.info file as the data is described in a .nyan file. That way you may have a mod that adds a new scenario, some random map script and a few new units, because you can create arbitrary folder hierarchies and configure the engine like the default data pack with nyan.

heinezen commented 6 years ago

I've got some ideas (rough draft) that I wrote to a gist here.

TheJJ commented 6 years ago

Current draft document: https://pad.stusta.de/p/openage-file-hierarchy

The sprite definition format is worked out in #965.

heinezen commented 4 years ago

A few things to discuss about the format:

Name and Identifier, provides field

I am with @timohaas here and don't think the name should be the identifier, since we'll probably deal with multiple sources for mods. There could be 50 mods that do the same thing, but only a few ways to spell it. I would rather use name + token/hash of something as an identifier.

The problem might arise for provides, conflicts or requires too when modders are not creative enough, e.g. I expect a lot of generic names like provides: villager-mod.

Description

There should probably a way for translating those, so I would put them into a folder and have description link there. It might also be helpful to have fields for both a short and a long description (The latter can be used with more details and use our markup language).

License

We should probably require this to either be empty or point to a file in the mod's folder. With URLs and names people can just come up with completely bogus rules afterwards and without control of the server or the previous license text, it's very hard to defend against malicious actors.

Authors

This could be expanded to include more things for authors to fill out. For example:

authors: alias_user <mail: bar@foo.com, fullname: Fooman Barstein, discord: bigdingeldein, patreon: https://xyz.com/>

For the people creating and sharing mods this is probably very important.

Maybe a separate field for author groups would be nice, so both the Ensemble Studios and all individual authors can be named.

mod

I don't know if this field is intended to also set the load order, but if it is, I would rather do it in the API. That way mods have more control over the load order of other mods and this might help them fix mod compatibility issues.