{"id":22293224,"url":"https://github.com/krateng/tirganach","last_synced_at":"2025-06-12T16:09:51.837Z","repository":{"id":227002973,"uuid":"770161932","full_name":"krateng/tirganach","owner":"krateng","description":"Library to edit SpellForce .cff files","archived":false,"fork":false,"pushed_at":"2024-03-20T13:54:54.000Z","size":92,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-25T22:17:10.629Z","etag":null,"topics":["binary-data","game-modding","spellforce"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/krateng.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-03-11T03:30:05.000Z","updated_at":"2024-03-16T17:52:12.000Z","dependencies_parsed_at":"2024-03-20T15:05:07.385Z","dependency_job_id":null,"html_url":"https://github.com/krateng/tirganach","commit_stats":null,"previous_names":["krateng/tirganach"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/krateng/tirganach","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krateng%2Ftirganach","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krateng%2Ftirganach/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krateng%2Ftirganach/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krateng%2Ftirganach/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/krateng","download_url":"https://codeload.github.com/krateng/tirganach/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krateng%2Ftirganach/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259500231,"owners_count":22867338,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["binary-data","game-modding","spellforce"],"created_at":"2024-12-03T17:28:07.651Z","updated_at":"2025-06-12T16:09:51.819Z","avatar_url":"https://github.com/krateng.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"A Python library for easier editing of the SpellForce `GameData.cff`.\n\nInformation about the file structure was gathered from\n* [Hokan-Ashir/SFGameDataEditor](https://github.com/Hokan-Ashir/SFGameDataEditor)\n* [leszekd25/spellforce_data_editor](https://github.com/leszekd25/spellforce_data_editor)\n\nIf you're here to reverse engineer the file / create your own library, have a look at [this short explanation](./EXPLANATION.md).\n\nHere's how you use `tirganach`:\n\n```python\nfrom tirganach import GameData\nfrom tirganach.types import *\nimport random\n\ngd = GameData('/games/SpellForce/data/GameData.cff')\n\n# let's make a cool item\nring = gd.armor.where(item_id=7065)[0]\nring.mana = 500\nring.health = 300\nring.item.name = \"Ring of Cheaters\"\n\n# make Azula one of our heroes\nsondra = gd.items.where(item_id=4425)[0]\nsondra.inventory_match.name = \"Rune Princess Azula\"\nsondra.name = \"Princess Azula\"\nsondra.unit_stats.head_id = 27\nsondra.unit_stats.size = 90 # canonically smol\n\nsondra.unit_stats.skills[0].set(skill_school=School.LIGHT_COMBAT, skill_level=20)\nsondra.unit_stats.skills[1].set(skill_school=School.LIGHT_BLADE_WEAPONS, skill_level=20)\nsondra.unit_stats.skills[2].set(skill_school=School.LIGHT_ARMOR, skill_level=20)\nsondra.unit_stats.skills[3].set(skill_school=School.RANGED_COMBAT, skill_level=15)\nsondra.unit_stats.skills[4].set(skill_school=School.BOWS, skill_level=15)\nsondra.unit_stats.skills[5].set(skill_school=School.ELEMENTAL_MAGIC, skill_level=20)\nsondra.unit_stats.skills[6].set(skill_school=School.FIRE, skill_level=20)\n\ncool_fire_spells = gd.spells.where(level=20, req1_class=School.FIRE)\nrandom.shuffle(cool_fire_spells)\n\nsondra.unit_stats.hero_spells[0].set(spell_id=cool_fire_spells[0].spell_id)\nsondra.unit_stats.hero_spells[1].set(spell_id=cool_fire_spells[1].spell_id)\nsondra.unit_stats.hero_spells[2].set(spell_id=cool_fire_spells[2].spell_id)\n\n# now let's make elves OP\nfor rune in gd.items.where(item_type=ItemType.RUNE_INVENTORY, item_subtype=RuneRace.ELVES):\n    rune.unit_stats.set(agility=120, dexterity=120, intelligence=120, wisdom=150)\n\ngd.save(\"/games/SpellForce/data/GameData.cff\")\n```\n\nCompare two versions:\n\n```shell\npython -m tirganach.compare GameData.cff GameData_patched.cff\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkrateng%2Ftirganach","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkrateng%2Ftirganach","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkrateng%2Ftirganach/lists"}