SpellForce 2 - Demons of the Past

SpellForce 2 - Demons of the Past

Not enough ratings
How to get some of the seemingly broken achievements
By artydent
  • issues with the spell-count achievements explained (incl. an exploit to get them faster)
  • mod to fix the end-of-game achievements
  • mod to fix Though Shalt Not Pass
2
   
Award
Favorite
Favorited
Unfavorite
Overview
Unfortunately, Spellforce 2 - DotP has several achievements that are seemingly broken.
I did some testing and some digging in the script files of the game to find out which ones are indeed broken and whether that can be fixed by a simple script modification.

Here's a quick overview. For details see the corresponding sections.



The spell-count achievements
Fire walk with me
Cast 40 Fireballs with the avatar
Handsome
Charm 50 enemies with the avatar
Fight fire with fire
Conjure 66 demons with the avatar
Can't touch this
Get invulnerable 75 times with the avatar
Cry baby
Cast Battle Cry 50 times with the avatar
If it bleeds, we can kill him
Hit enemies with Slash 50 times
Seven sins
Cast Salvo (Master) 40 times
True Dragon
Cast 200 shaikan spells
actually work but the counting isn't accurate due to some implementation issues. This often means that more castings than stated are necessary but it also allows for an exploit to get some of the achievements much faster.



The five achievements
The last march
Complete Forest of Argan
Knowledge is power
Complete Demons of the Past on Easy or Normal level
Power leads knowledge
Complete Demons of the Past on Difficult level
Master Investigator
Complete Demons of the Past on Very Difficult level
Thou shalt not pass
Close every gate after opening them
are actually broken but can be fixed with simple modifications.

The achievement script in the game actually checks corresponding flags to trigger the achievements, but those those flags are never set anywhere. (At least not in any of the campaign scripts like it is the case for the other achievements.)



The hidden achievements
Kubi Rule
Kubi rule them all
Urban Law
The developers law
are most likely broken. Technically fixable but I don't indend to fix them without knowing the original intent behind them.

The achievements can easily be triggered with a simple script modification. But they would have to be triggered on some arbitrary conditions, and I'd consider that cheating.
Unfortunately, none of the script files contained anything related that would indicate what the original intent might have been.



All other achievements are properly handled within the script files (and properly triggered for me).
If they don't trigger for someone, then they either missed something or some other bug is at play.
Issues with (and exploit for) the spell-count achievements
Fire walk with me
Cast 40 Fireballs with the avatar
Handsome
Charm 50 enemies with the avatar
Fight fire with fire
Conjure 66 demons with the avatar
Can't touch this
Get invulnerable 75 times with the avatar
Cry baby
Cast Battle Cry 50 times with the avatar
If it bleeds, we can kill him
Hit enemies with Slash 50 times
Seven sins
Cast Salvo (Master) 40 times
True Dragon
Cast 200 shaikan spells

Some of those achievements have occasionally been reported as broken. In principle they all work though, but not always as expected. Here's what you should be aware of when trying to get them:
  • Spells are counted only in Campaign Mode, not in Free Game or any other modes.
  • Casting with different avatars is NOT cumulative for the achievement. And progress is lost if you keep playing from an earlier savefile.
  • Sometimes, casting the right spell simply doesn't count for the achievement. (See technical details below for an explanation.) In particular, if you cast multiple Shaikan spells in quick succession, usually just one will count for the True Blood achievement.
    Unfortunately, there is no way to see whether a spell just counted or not.
  • The description of If it bleeds, we can kill him is a bit misleading. It's also just about how often the avatar is casting the spell.
  • For each of those achievements, both the basic version and the mastered version of the spell work. (Even for Seven sins the basic spell works. The description is misleading.)
  • If the spell requires a target and the avatar is too far away, the spell counter is repeatedly increased (about every 5-6 seconds) while the avatar moves towards the target. (See technical details below for an explanation.)
    This can be exploited to farm those achievements relatively quickly: With a very long way to the spell target (or by repeatedly switching between two targets in opposite directions) it's possible to get the achievement without actually casting the spell, which eliminates any waiting time for recharging the spell or the mana.



For anyone interested, here are the technical details:

All achievement detection is script-based. There is an achievement script (which is only used for the campaign) that deals (among other things) with the spell counting for the achievements.
The script attempts to detect when the player is casting an achievement-relevant spell, and upon successful detection an associated counter is increased. Those counters belong to the avatar and are regularly saved/loaded when you save/load your game, that's why progress for such an achievement can't be split between different games.

Now to the more technical part of how the script attempts to detect spell casting.
For each of those achievements, the script defines an event handler that (when enabled) keeps checking whether the avatar is currently in the process of casting one of the relevant spells. However, the event handler has a built-in delay between those checks (about 2-3 seconds for me, but that might also depend on the computer). Maybe this is done to not put the script engine under too much stress, or maybe just as a measure to avoid multiple detections for a single casting. Anyway, the side effect is that an unfortunately timed spell - even though the casting itself takes 1-2 seconds - might happen right inbetween two checks and is therefore not counted towards the achievement. There is still a good chance that a (randomly timed) spell is detected though. (But of course there is the possibility that a too regular spell casting - e.g. when farming for such an achievement - might accidentally fall right into the detection gap every single time, so better keep some randomness in the timing.)

There is more to it. After the mentioned event handler detects a spell and responds to it, it automatically becomes disabled. Now it would be bad if it stayed disabled, because no further spell could be detected, so in addition to increasing the spell counter the handler also re-enables a second event handler. That one checks whether the first handler is disabled and then re-enables it and becomes disabled itself. (I am not 100% sure why it is done this way, considering that in some other places the game actually uses event handlers that can act repeatedly without disabling. Those aren't used often though, in fact most repeat events in the game are done with this disabling and re-enabling. There might be some technical reason for this.) This second event handler also has a built-in delay between its checks (slightly longer than the first), which means that after an achievement-relevant spell is detected, there is a longer delay (combination of the delays of the two handlers, about 5-6 seconds for me) until another spell for that achievement can be detected. (There is an exception for the first detection on any map, but let's not get too technical here.) That delay is mainly an issue for the True Blood achievement when someone casts multiple spells in quick succession (because a single event handler is used for all the associated spells). All the other achievements only have a single associated spell anyway, so the recharge time usually prevents to cast it in quick succession. (But maybe with a lot of equipment that reduces recharge times, this can become an issue for other achievements, too.)

Now to the exploit. When a spell targets something further away and there is a movement path to it, then the game apparently considers the avatar to be already casting while moving towards the target. Which means that the first event handler quickly triggers and increases the spell counter, gets disabled but re-enabled after a delay, triggers again after a delay and so on. Due to the combined delay of both event handlers, spell detection (and thus counter increase) happens every 5-6 seconds.
Fix (mod) for the end-of-game achievements
The last march
Complete Forest of Argan
Knowledge is power
Complete Demons of the Past on Easy or Normal level
Power leads knowledge
Complete Demons of the Past on Difficult level
Master Investigator
Complete Demons of the Past on Very Difficult level

Here's a simple mod (you only need a basic text editor) to trigger those achievements the way they were intended. Technically, this is a bit of cheating though, so don't do it if that makes you uncomfortable.

IMPORTANT: The modification will only have an effect on games where the final map wasn't entered yet. So you'll have to reload a save from before and replay the final map.

Step 1: Find the steam library (the one you use for SF2-DotP) on your hard drive and find the "SpellForce 2 - Demons of the Past" folder in it. Enter the sub folder "addon3/map/Campaign/P710_West_Westguard/script/". All modifications will be done here.

Step 2: Create a new file "Achievements.lua" (or name it however you want) in this folder. Open the file in a text editor and copy the following into it.
-- Fix to trigger the end of game achievements properly State { StateName = "INIT", OnOneTimeEvent { EventName = ">>> achievement: map completed <<<", Conditions = { QuestIsSolved {Player = "default", Quest = "ADDON3_MAP09_LUREZAZHUT"}, }, Actions = { AvatarFlagSetTrue {Player = "default", Name = "af_Achievement_P710_Completed"}, }, }, OnOneTimeEvent { EventName = ">>> achievement: game completed on EASY or NORMAL <<<", Conditions = { QuestIsSolved {Player = "default", Quest = "ADDON3_MAP09_LUREZAZHUT"}, OR { GameDifficulty {Value = 1}, GameDifficulty {Value = 2}, }, }, Actions = { AvatarFlagSetTrue {Player = "default", Name = "af_Achievement_DotP_Completed"}, }, }, OnOneTimeEvent { EventName = ">>> achievement: game completed on DIFFICULT <<<", Conditions = { QuestIsSolved {Player = "default", Quest = "ADDON3_MAP09_LUREZAZHUT"}, GameDifficulty {Value = 3}, }, Actions = { AvatarFlagSetTrue {Player = "default", Name = "af_Achievement_DotP_Completed_Difficult"}, }, }, OnOneTimeEvent { EventName = ">>> achievement: game completed on VERY DIFFICULT <<<", Conditions = { QuestIsSolved {Player = "default", Quest = "ADDON3_MAP09_LUREZAZHUT"}, GameDifficulty {Value = 4}, }, Actions = { AvatarFlagSetTrue {Player = "default", Name = "af_Achievement_DotP_Completed_VeryDifficult"}, }, }, };
This is the code that will actually check the proper conditions and set the flags that will then trigger the achievements as intended.

Step 3: Open the file "_P710_West_Westguard_ScriptList.lua" in a text editor and add the name of your newly created file to the list, i.e., add a line
"Achievements.lua",
somewhere within the scope of those curly brackets. That's necessary to make the game aware of your new file.

Step 4: Open the file "MQ_Addon3_Map09_LureZazhut.lua" in a text editor. Find the following place in the file
OnOneTimeEvent { Conditions = { MapTimerIsElapsed {Name = "mt_P710_EndVideoTimer", Seconds = 2}, }, Actions = { MapTimerStop {Name = "mt_P710_EndVideoTimer"}, PlayerGameEnds {}, }, },
and change the number of seconds to 5 (or even higher if you want). This will give the script enough time after the final cutscene to trigger the achievements before the game abruptly ends.

Step 5 (optional): In the same file find the line
CutscenePlayBinkVideo {File = "addon3/video/outro.bik"},
(which should be in the event above the one you edited in the step before). After that line simply add the line
FigureVanish {Tag = "ZazhutLure"},
This step isn't strictly necessary. It simply removes Zazhut from the map after the final cutscene (in which he was defeated). Apparently, the developers didn't bother to do that but instead just abruptly ended the game. With the additional seconds from the previous step though, it is weird (and potentially deadly) if Zazhut is still fighting you at that point.

Done! Replay the final map (remember: load a savegame from before entering the map for the first time) and enjoy getting the achievements.

Btw, there is no need to replay the map on each difficulty. You can simply change the difficulty shortly before the end. (I considered being stricter and requiring a full play-through of this map without changing difficulty inbetween, but all the other difficulty-dependent achievements also allow this "cheat".)
Fix (mod) for Thou Shalt Not Pass
Thou shalt not pass
Close every gate after opening them

For this achievement it's not 100% clear what the exact intent had been. Here's a simple mod (you only need a basic text editor) to trigger this achievement in a way that at least fits the description without making it too trivial. Technically, this is a bit of cheating though, so don't do it if that makes you uncomfortable.

IMPORTANT: The modification will only have an effect on games where the Citadel map was never entered yet. So you'll have to reload a save from before that and replay the map (or at least parts of it until you get the achievement).

Step 1: Find the steam library (the one you use for SF2-DotP) on your hard drive and find the "SpellForce 2 - Demons of the Past" folder in it. Enter the sub folder "addon3/map/Campaign/P704_The_Citadel/script/". All modifications will be done here.

Step 2: Open the file "Achievements.lua" in a text editor. Find the following place in the file
OnOneTimeEvent { EventName = ">>> achi: gates closed <<<", Conditions = { SetUpdateInterval {Steps = 10}, --- ??? MapFlagIsTrue {Name = "mf_P704_xxx"}, }, Actions = { AvatarFlagSetTrue {Name = "af_Achievement_P704_Closed"}, }, },
and replace this part by
OnOneTimeEvent { Name = "Event_Achi_All_Gates_Open", Conditions = { SetUpdateInterval {Steps = 20}, GateIsOpen {Tag = "Gate2"}, GateIsOpen {Tag = "Gate4"}, GateIsOpen {Tag = "Gate5"}, GateIsOpen {Tag = "Gate6"}, }, Actions = { MapFlagSetTrue {Name = "mf_P704_Gates_Opened"}, }, }, OnOneTimeEvent { EventName = ">>> achi: gates closed <<<", Conditions = { SetUpdateInterval {Steps = 20}, MapFlagIsTrue {Name = "mf_P704_Gates_Opened"}, GateIsClosed {Tag = "Gate2"}, GateIsClosed {Tag = "Gate4"}, GateIsClosed {Tag = "Gate5"}, GateIsClosed {Tag = "Gate6"}, }, Actions = { AvatarFlagSetTrue {Name = "af_Achievement_P704_Closed"}, }, },

Done! Enter the Citadel map (remember: load a savegame from before entering it for the first time), open all the gates you can, close all the gates you can, and get the achievement.

Hints to get the achievement: There are only four gates that you can open and also close. All four must be open at some point, later all four must be closed. If you don't know where to find the levers, you could just start the quests for all four factions, each one has an "open gate" quest for one of these gates.

Additional remark: Given the name of the achievement I assume that the original intent might have been more complex, involving cutting off attack routes for the factions. To implement this (without breaking things) would have required significantly more changes though (adding some lever handling, modifying attack routes accordingly, etc.). I didn't consider it worthwhile to attempt this, especially because the scripts for this map are already quite complex and a lot of things on this map are unfinished or buggy anyway.
10 Comments
lukenewitsch May 24 @ 3:46am 
Actually you can also exploit the achievements for invulnerable and battle cry:
a) Start the spell,
b) wait a bit (about one second)
c) move you character before the spell gets castet.
d) repeat.

For battle cry in needed about 150 repetitions of above steps to get the achievement awarded.
If case you accidentially cast the spell, no issue, then you need to wait until it can be casted again.
This procedure helps to skip the cooldown-time.
Aliaxi Nov 30, 2023 @ 12:46pm 
With Thou shalt not pass i can only open and close 3 gates. So even with the script adjustment still am unable to get it by closing and opening gates.
The gate at the top the lever gets stuck after opening it. You can't close that one anymore.
Machette :] Jun 3, 2022 @ 12:59am 
Its not working for me bro, its says error platform switch. did everything like in a instructions :/ talkin bout last 4 achievements with finishing the game, huulp
death_metalhead Feb 5, 2022 @ 1:36pm 
Thanks for this guide. It worked for me. After applying the Fix (mod) for the end-of-game achievements, open the file addon3\script\Achievements.lua and change 'ach_dotp_completed' to 'ach_dotp_kubi_rule' OR 'ach_dotp_completed' to 'ach_dotp_urban_law' and save. Done! Replay the final map on easy or normal (remember: load a savegame from before entering the map for the first time) and enjoy getting the achievements.
Tineard Nov 9, 2021 @ 7:17am 
Hey-hey! Thank you for posting this.
But I assume, everyone is stuck now on 2 last hidden achievements.
Maybe I misunderstood, but did you say in comments earlier, that you actually got info on those 2? If so, can you share it? As I understand, you will create patch (or guide?) to make those work later, but it's been half a year, so it would be nice to at least know, what is up with those. Are those broken? Is it some scripting mistake? Or someone forgot to even put those achievements into the game? Thanks in advance :)
Arimdaar Silversword May 20, 2021 @ 12:16pm 
@artydent

Hello!

Can't wait about this community patch to be done. Thank you so much for your hard work! I thought I won't get achievements completion at all.

Have a nice day!
Pan Maruda Apr 22, 2021 @ 11:27am 
I'm very grateful to your work. Today is the day I 100% this godforsaken pice of buggy game. Again thank you for your hard work to fix that, what the Devs didn't care to do. To anyone finding this little guide, give a like, @arttdent earned it well. May the Guardians guide you.
artydent  [author] Apr 17, 2021 @ 1:36pm 
I know the Spanish post, but those guesses weren't quite correct. I already got the correct answers from the SF-community on their discord server. I was actually making an expansion to the community patch which will include all the missing achievements and some other fixes. It's almost done even, but other stuff came up, so it's been on hiatus for the past few months. I'll try to find some time within the next few weeks to finish and release it though.
Maysamtab Apr 11, 2021 @ 4:27am 
@artydent

Hi,

thanks for the post, it was very helpful.
by the way I found a post in Spanish about the two secret achievements
the google translate is as follow:

"I've been looking at the game thoroughly, and of the 55 existing achievements, only 53 have any events that activate them. The missing ones are the 2 that are supposedly secret. They are so secret that they do not exist, only their identifier: "ach_dotp_urban_law" and "ach_dotp_kubi_rule".

"Urban Law" may have been intended to be obtained if Survival mode was won, because in the final 2 waves we fight the developers ("The developers law" is the definition of the achievement).
"Kubi Rule" may have been intended to be obtained if Domination mode was won. It seems obvious, because the objective in this way is to dominate everyone ("Kubi rule them all"). I don't really know what that "Kubi" means, although there is a "Kubisforce" as the name of one of the developers, and it may be the name of one of them."
JanusXi Feb 10, 2021 @ 1:14pm 
Thank you!