|
|
Drake
Adventuring Hero
Satisfying no one since 1994
|
posted February 13, 2020 01:52 AM |
|
|
Bersy said: HoMM 3 ERA update released
Current version: 2.9.10
Awesome! Is it safe to install over previous update?
____________
~Drake Lyon~
|
|
Bersy
Honorable
Supreme Hero
|
posted February 13, 2020 01:58 AM |
|
|
|
Drake
Adventuring Hero
Satisfying no one since 1994
|
posted February 13, 2020 02:06 AM |
|
|
Bersy said: Welcome! Delete ModsWoGDatas manually in case of installing over previous version.
Thank you!
____________
~Drake Lyon~
|
|
Archer30
Adventuring Hero
|
posted February 14, 2020 09:01 AM |
|
Edited by Archer30 at 15:49, 14 Feb 2020.
|
Hmm I think I've found something
"Veil" is ok but the building is actually Cover of Darkness. Maybe just remove the title like the other specialties?
Rebuilding
|
|
xericsin
Famous Hero
|
posted February 14, 2020 11:53 AM |
|
|
There are a few ways of adding condition (say &v1=1) to a function (say FU1234).
I am wondering on efficiency of code regarding where to put the conditioning. Hope someone can help. Maybe @Bersy? Thanks in advance.
I know the difference is almost nothing for a modern computer, but I am just curious.
Case [1] and [2] are the same. The condition is checked after FU1234 is called, meaning relevant memories like y-vars of the previous function are pushed into stack, and will be restored after FU1234 ends. In the case of condition being false (say v1=0), redundant pushing stack occurs for FU1234.
[1]
!?FU1234&v1=1;
[2]
!?FU1234;
!!FU&v1=1:E;
Case [3] and [4] are the same. The condition checking is done before calling FU1234. If condition is false, FU1234 is skipped and no pushing stack occurs for FU1234.
[3]
!?FU1;
!!FU1234&v1=1:P;
[4]
!?FU1;
!!if&v1=1:;
!!FU1234:P;
!!en:;
Hence,
1. Am I right to say case [3] and [4] are more efficient than [1] and [2]?
2. What is the approximate workload preparing for function calling in the case of ERM? Is it at the 100 or 1000 y-var operations level?
|
|
Bersy
Honorable
Supreme Hero
|
posted February 14, 2020 03:44 PM |
|
|
Archer30, fixed "rebuilding", thanks. You can try to change Veil to cover in exe file using any binary file editor like Bied.exe, but Veil is used in hero biography and other places.
xericsin, In 2.9.x I optimized ProcessErm function.
1) If trigger with necessary ID is not found, it's not processed. I mean save/restore vars blocks are not executed. Of course, all handlers are checked, including plugins/lua handlers.
NumericEventName := 'OnTrigger ' + SysUtils.IntToStr(TriggerId);
HumanEventName := Erm.GetTriggerReadableName(TriggerId);
HasEventHandlers := (StartTrigger.Id <> 0) or EventManager.HasEventHandlers(NumericEventName) or EventManager.HasEventHandlers(HumanEventName);
Triggers are stored in sorted order and cache-optimized variant of binary search is used to detect the first one. Thus, from now, it does not matter, whether you have 1 trigger in scripts or 4000 different triggers. In old times linear search was used, thus calling any trigger caused many cache misses and full linked list scanning.
2) In Era 2.9+ local variables are saved/restored only once for particular trigger ID.
; saved state, inited flags and quickvars
!?CM2;
!?CM2;
!?CM2;
; restored state
With ErmLegacySupport=1 in heroes3.ini some variables are saved/restored exactly as in 3.58 for compatibility with old scripts.
3) Condition on trigger is faster, than executing
!!FU&...:E; but it really matters only in 100000+ iterations
Probably, 2x faster, but I didn't test, because premature optimization IS EVIL.
For instance, in former times a linear search for ERM receiver name was performed: 100+ receivers list of name + handler. I replaced it with precompiled handler address stored in ERM receiver itself. Thus O(n) -> O(1) reduced complexity. Tested — no gain. Really, almost no speed gain.
4) !!if block is a bit slower, because linear scanning is performed before !!en command is found, but single ERM execution is usually so slow, that it does not matter again.
In my tests you can have 1 500 000 receivers/second in !!re loop or 1 300 000 using !!DO or !!SN:G. !!DO is heavily optimized now, !!re is even better, unless code becomes more readable, when extracted to separate function. In Era 2.8.8 we had 130 000 receivers/second performance in loops.
____________
Heroes 3 Era and everything for it. Releases folder for releases.
|
|
Archer30
Adventuring Hero
|
posted February 14, 2020 04:04 PM |
|
|
Bersy said: You can try to change Veil to cover in exe file using any binary file editor like Bied.exe
I'll try this one. Thanks!
|
|
xericsin
Famous Hero
|
posted February 14, 2020 06:35 PM |
|
|
@Bersy OK. Roughly understood.
I forgot to mention the comparison of these 2 cases, which is quite essential to me. I see the premature optimization IS EVIL, but just pain in my eyes.
[1]
!!FU1234;
!?FU1234&v1=1;
[2]
!!FU1234&v1=1;
!?FU1234;
FU1234 will rarely be called as the condition will rarely be met (1/100 chance).
So, I am putting the condition on the receiver [2] instead of putting on the trigger [1], hoping this would help spare the time for variable saving and restoring. Does this make sense?
I am actually doing something like this. I am not writing the code for a creature directly under !?BG0. I add FU(BG0) for better organization, but it slows down the process. And the newer era does not really help in my case. So, I am looking for simple ways to improve this - place of conditioning.
!?BG0;
!!FU(BG0_DelayedDamage);
!!FU(BG0_AICrCast_Routine);
!!FU(BG0_Bef_CastMove);
!!FU(BG0_GoldDragon);
!!FU(BG0_DreadKnight);
!!FU(BG0_OrcChieftain);
!!FU(BG0_Troglodyte);
!!FU(BG0_SneakyStrike_X);
!!FU(BG0_Demon_Dash);
!!FU(BG0_PreStrike_X);
!!FU(BG0_Tent_Close_Dummy);
!!FU(BG0_Aft_Select_Action);
!!FU(BG0_DwarfMino_Count_Start);
|
|
Bersy
Honorable
Supreme Hero
|
posted February 15, 2020 03:45 PM |
|
|
Right, not calling trigger at all is faster, that calling it.
I suggest you to test everything using the following snippet:
!?CM0;
!!UN:C6529876/4/?y1; y1 - timeGetTime function
!!SN:Ey1/1;
!!VRy2:Sv1;
; write your test code here, repeatedly call functions, etc
!!SN:Ey1/1;
!!VRy3:Sv1-y2;
!!IF:M^Ellapsed %Y3 msec^;
!!CM:R0;
!!SN:Q;
-----------------------------------------
For !?BG0 even 200 function calls should have almost no delay time. Perhaps, functions themselves contain slow loops. Which Era version do you use? Because your code organization is valid and of high level.
____________
Heroes 3 Era and everything for it. Releases folder for releases.
|
|
yunings
Hired Hero
Elf paladin
|
posted February 15, 2020 06:31 PM |
|
Edited by yunings at 18:33, 15 Feb 2020.
|
Hi Bersy
I set up ERA2.9.10 by brand new installation, but the game was reported wrong at the early stage of running. It seems to be the problem of script 75, so I don't know how to solve it.Please refer to my screenshot for specific error report.I can also attach the archive if necessary.
[url=https://imgchr.com/i/3SKW0P][/url]
____________
[url=http://bbs.wakeofgods.com/index.php?styleid=3&sid=LTEqPK]Welcome to Chinese WoG Forum![/url]
|
|
Bersy
Honorable
Supreme Hero
|
posted February 15, 2020 08:52 PM |
|
Edited by Bersy at 20:53, 15 Feb 2020.
|
Hi, yunings!
We've detected multiple bugs in script 75, that were hidden due to buggy old ERM engine.
Try this one
----------------
ERM 2.0 is on approch: named local variables and arrays.
!?FU(dex_SetDwellingSlotByTownType);
; Configures monster slot for all towns of specific type
; $xTownType$
; $xDwellingLevel$
; $xUpgraded$
; $xSlot$
; $xMonType$
; $xGrowth$
;
; Example: FU(SetTownsDwellingSlot):P1/0/1/2/13; set Rampart 3-d alternative for upgraded centaures to Archangels.
!!VR$yDwellingId$:S$xUpgraded$ *7 +$xDwellingLevel$;
!!VR$yMonType$:S$xMonType$ +2;
!!SN:W^dex.T$xTownType$ D$yDwellingId$ S$xSlot$^/$yMonType$;
____________
Heroes 3 Era and everything for it. Releases folder for releases.
|
|
yunings
Hired Hero
Elf paladin
|
posted February 16, 2020 01:39 AM |
|
|
Got it!
____________
[url=http://bbs.wakeofgods.com/index.php?styleid=3&sid=LTEqPK]Welcome to Chinese WoG Forum![/url]
|
|
yunings
Hired Hero
Elf paladin
|
posted February 16, 2020 01:49 AM |
|
|
I replaced it with the script you provided, created a new game, and the problem remains.And I noticed that it always seemed to happen on the sixth day.
____________
[url=http://bbs.wakeofgods.com/index.php?styleid=3&sid=LTEqPK]Welcome to Chinese WoG Forum![/url]
|
|
daemon_n
Known Hero
|
posted February 16, 2020 05:55 AM |
|
|
yunings said: I replaced it with the script you provided, created a new game, and the problem remains.And I noticed that it always seemed to happen on the sixth day.
Try this:
Find
!!VRv912:Sv902 %21; [get an actual slot number]
And edit to the
!!VRv912:Sv902 %7; [get an actual slot number]
For me that works, but i wanna more tests
For the assembly of course
|
|
xericsin
Famous Hero
|
posted February 16, 2020 09:04 AM |
|
|
Bersy said: Right, not calling trigger at all is faster, that calling it.
I suggest you to test everything using the following snippet:
!?CM0;
!!UN:C6529876/4/?y1; y1 - timeGetTime function
!!SN:Ey1/1;
!!VRy2:Sv1;
; write your test code here, repeatedly call functions, etc
!!SN:Ey1/1;
!!VRy3:Sv1-y2;
!!IF:M^Ellapsed %Y3 msec^;
!!CM:R0;
!!SN:Q;
-----------------------------------------
For !?BG0 even 200 function calls should have almost no delay time. Perhaps, functions themselves contain slow loops. Which Era version do you use? Because your code organization is valid and of high level.
Great. Thanks.
|
|
yunings
Hired Hero
Elf paladin
|
posted February 16, 2020 10:44 AM |
|
|
daemon_n said:
yunings said: I replaced it with the script you provided, created a new game, and the problem remains.And I noticed that it always seemed to happen on the sixth day.
Try this:
Find
!!VRv912:Sv902 %21; [get an actual slot number]
And edit to the
!!VRv912:Sv902 %7; [get an actual slot number]
For me that works, but i wanna more tests
For the assembly of course
It seems to be working.I will do more tests to verify, thank you very much, Daemon!
____________
[url=http://bbs.wakeofgods.com/index.php?styleid=3&sid=LTEqPK]Welcome to Chinese WoG Forum![/url]
|
|
Archer30
Adventuring Hero
|
posted February 17, 2020 06:23 PM |
|
Edited by Archer30 at 07:35, 19 Feb 2020.
|
Hi Bersy,
There is an issue with scholar enhancement (30 wog - enhanced secondary skill.erm) that might crash the game. Check this save out, end the turn and the game crashes on Brown's turn.
I tried to apply Algor's fix to this script and it's all good now.
|
|
Bersy
Honorable
Supreme Hero
|
posted February 17, 2020 08:21 PM |
|
Edited by Bersy at 20:26, 17 Feb 2020.
|
Hi, Archer30!
I'm working on Era 2.9.11 with ERM 2.0 support (named local and global variables everywhere) and extracted WoG Scripts to a separate mod. To say the truth, supporting old-style and buggy scripts is a burden I'm transferring to community. I hope, starting from Era 2.9.11 no WoG skin/campaigns/scripts will be supplied with base package, only high-level tools, script engine and help.
I think, we need more and more script writers, that may write scripts using language json files and SN:T, !!re for loops and named local/global variables.
Example of higher-level ERM:
!?FU(dex_SetDwellingSlotByTownType);
; Configures monster slot for all towns of specific type
; $xTownType$ - town type (0 for castle, 1 for rampart, etc)
; $xDwellingLevel$ - dwelling level (0..6)
; $xUpgraded$ - upgraded or not (1 or 0)
; $xSlot$; - slot ID (0..3)
; $xMonType$ - alternative monster type, -1 to make slot empty
; $xGrowth$ - Optional. Growth rate in percents (100 = original, 50 = twice lower, 200 = twice higher, -1 for manual growth, (1000 + weekly growth) * -1 for auto-growth). In case of auto-growth Citadel, Castle and Grail buildings will increase growth additionaly by 50%/100%/150%.
;Default: 100.
;
; Example: FU(SetTownsDwellingSlot):P1/0/1/2/13; set Rampart 3-d alternative for upgraded centaures to Archangels.
!!VR$yDwellingId$:S$xUpgraded$ *7 +$xDwellingLevel$;
!!VR$yMonType$:S$xMonType$ +2;
!!SN:W^dex.T$xTownType$ D$yDwellingId$ S$ySlot$^/$yMonType$;
!!FU:A?k;
!!VR$xGrowth$|k<6/$xGrowth$=0:S100;
!!SN:W^dex.TG$xTownType$ D$yDwellingId$ S$xSlot$^/$xGrowth$;
!!UN&$xSlot$>=0/$xSlot$<=1:T$xTownType$/$xDwellingLevel$/$xUpgraded$/$xMonType$; change native town dwelling settings
____________
Heroes 3 Era and everything for it. Releases folder for releases.
|
|
Hero_of_Light
Responsible
Supreme Hero
|
posted February 17, 2020 11:38 PM |
|
|
@Bersy
Since others pointed out the issue as well, can you come up with a way to remove the annoying Builder and Veil of Darkness ability that is forced upon Jeddite and Nagash? It is irritating how their speciality description changes upon restarting a game. Isn't there a plugin or ERA command to remove this?
____________
Not idly do the leaves of Lorien fall.
|
|
Bersy
Honorable
Supreme Hero
|
posted February 18, 2020 12:54 AM |
|
|
|
|