Thanks i will take a look at that.Maroon said:There's a multitude of ways mods can be optimized, based on what area is causing a slowdown issue to begin with. Personally, lately I have improved performance by scaling down specular and normal map sizes (making them 512x512 if their main texture is 1024x1024, for example). This saves on mod size, and helps prevent issues when there's a lot of textures in your mod (not really an issue for most mods though).
Using proper shaders for your materials, creating good LODs, not overusing flora props on a map. All these things can help improve a mod's stability outside of scripting.
I'm worried that the size of 1257's map and the amount of parties will slow things down on the user's end. For now i slowed down a few simple triggers that weren't all that important and ran on less than 6 hour period.Kentucky James said:What are your performance issues? Is there stuttering or lag or just a low framerate, and where?
Knowing where you have issues is the first thing you should do in diagnosing poor performance. A solution for one framerate problem might cause extra issues if you implement it somewhere it's not needed, etc.
Leonion said:gsanders said:2) Consider the following triggers: one hourly, one at 2 hours, one at 4 hours, one at 8 hours, one at 24 hours, one weekly.
the next week, at the same time I'm processing the weekly trigger, also firing at that exact instant is the 24 hour, the 8 hour, the 4 hour, the two hour, and every single 1 hour trigger -- ALL AT ONCE.
The artful solution is to move as many triggers to prime numbers to slightly different timing so they don't fire at the same time, spreading the hit on performance out across time.
NO.
This is a bad idea.
I've seen your optimization in Perisno and I thought 'wow, that's a cool solution', and followed like a sheep doing this to more triggers, but months later I tested it and we both underestimated the intelligence of TW devs.
Counters of all triggers of the same frequency start at different times, they're given different offsets at the start of the game.
I.e., you have 10 24-hour triggers, but they will trigger at different time, not at once.
Whole numbers (like 24, 6, 4) are actually almost a guarantee that triggers will never be triggered at the same time, because they started running at different time and there is no change in their "pace".
Fractional triggers, however, have different "pace", so sooner or later they will intersect with each other, having "compensated" that offset that was given to them at the start of the game by the engine.
You can easily test it by creating multiple triggers of the same frequency or frequency that is 'part' of the largest one (sorry, my math English vocabulary is non-existent), like 2, 4, 6, 8, 24 and adding display_message operations like "Trigger 1/2/3/4 was called!" to each.
You won't receive these messages at the same time.
______________________________________________________
So this is not a way to optimize triggers.
The best ways are indeed getting rid of big try_for_parties triggers and diving large triggers into parts, like that enormous faction AI trigger that does a lot of calculations for all factions at once:
Code:(0, [ (eq, "$g_recalculate_ais", 1), (assign, "$g_recalculate_ais", 0), (call_script, "script_recalculate_ais"), ]),
Code:(0.1, [ (try_begin), (is_between, "$g_recalculate_ais_cur_fac", kingdoms_begin, kingdoms_end), (try_begin), (faction_slot_eq, "$g_recalculate_ais_cur_fac", slot_faction_state, sfs_active), (call_script, "script_recalculate_ais_for_faction", "$g_recalculate_ais_cur_fac"), (else_try), (assign, ":cycl_end", kingdoms_end), (assign, ":cycl_beg", "$g_recalculate_ais_cur_fac"), (try_for_range, ":faction_no", ":cycl_beg", ":cycl_end"), (faction_slot_eq, ":faction_no", slot_faction_state, sfs_active), (assign, "$g_recalculate_ais_cur_fac", ":faction_no"), (call_script, "script_recalculate_ais_for_faction", "$g_recalculate_ais_cur_fac"), (assign, ":cycl_end", 0), (try_end), (try_end), (else_try), (assign, "$g_recalculate_ais_cur_fac", kingdoms_begin), (call_script, "script_recalculate_ais_for_faction", "$g_recalculate_ais_cur_fac"), (try_end), (val_add, "$g_recalculate_ais_cur_fac", 1), ]),
# Setting random walker types
(36,
[(try_for_range, ":center_no", centers_begin, centers_end),
(this_or_next|party_slot_eq, ":center_no", slot_party_type, spt_town),
( party_slot_eq, ":center_no", slot_party_type, spt_village),
(call_script, "script_center_remove_walker_type_from_walkers", ":center_no", walkert_needs_money),
(call_script, "script_center_remove_walker_type_from_walkers", ":center_no", walkert_needs_money_helped),
(store_random_in_range, ":rand", 0, 100),
(try_begin),
(lt, ":rand", 70),
(neg|party_slot_ge, ":center_no", slot_town_prosperity, 60),
(call_script, "script_cf_center_get_free_walker", ":center_no"),
(call_script, "script_center_set_walker_to_type", ":center_no", reg0, walkert_needs_money),
(try_end),
(try_end),
]),
# Setting random walker types
(0.049, ################## once every 36 hours for each of the 733 centers
[
(try_begin),
(lt, "$g_set_random_walker_types_cur_center", centers_begin),
(assign, "$g_set_random_walker_types_cur_center", centers_begin),
(try_end),
(try_begin),
(ge, "$g_set_random_walker_types_cur_center", centers_end),
(assign, "$g_set_random_walker_types_cur_center", centers_begin),
(try_end),
(try_begin),
(this_or_next|party_slot_eq, "$g_set_random_walker_types_cur_center", slot_party_type, spt_town),
(party_slot_eq, "$g_set_random_walker_types_cur_center", slot_party_type, spt_village),
(call_script, "script_center_remove_walker_type_from_walkers", "$g_set_random_walker_types_cur_center", walkert_needs_money),
(call_script, "script_center_remove_walker_type_from_walkers", "$g_set_random_walker_types_cur_center", walkert_needs_money_helped),
(store_random_in_range, ":rand", 0, 100),
(try_begin),
(lt, ":rand", 70),
(neg|party_slot_ge, "$g_set_random_walker_types_cur_center", slot_town_prosperity, 60),
(call_script, "script_cf_center_get_free_walker", "$g_set_random_walker_types_cur_center"),
(call_script, "script_center_set_walker_to_type", "$g_set_random_walker_types_cur_center", reg0, walkert_needs_money),
(try_end),
(try_end),
######## proceeds to the next center when it's triggered again
(val_add, "$g_set_random_walker_types_cur_center", 1),
]),
xenoargh said:Also, the Horseman AI is a huge CPU hog, for whatever reasons; be aware that an Agent riding a Horse is somewhere on the order of 4-5 times as expensive, per frame, as infantry.
Isn't it the GPU that processes *skin* shaders?xenoargh said:LODs, guys. Don't make content without carefully considering LODs and overall load; every single mesh attached to live Actors costs quite a lot of CPU.
No, the offset is applied to module_triggers too.Kentucky James said:So is this automatic offset only in simple_triggers? Do triggers offset to any point within the range of the trigger, or is it all staggered to within an hour or something? Is that the same for the battle triggers?
Can you elaborate on this? What kind of problems could this cause?xenoargh said:great caution must be used when writing anything that operates within a one-frame context. Don't write that Ultra-Kewl Presentation unless it's really, really actually necessary to gameplay.
xenoargh said:Simplest answer is that if it's heavily recursive, requires any Fancy Math (vector math, distances, etc.) and it runs every frame, you can drag framerates down super-fast.