[WB][S][TC]EmpireIV Ver. 1.0 [WSE for EmpireIII 64 bit OS required]

Users who are viewing this thread

Status
Not open for further replies.
gsanders said:
Buckethell said:
..., PLEASE, fix the performance issues.
The game in my opinion is currently unplayable, and i really want to play it, because it looks amazing.
The lag is real and the loadings are too much long, even if you enter and exit from a village it takes 15 secs everytime, and i can't even fast-forwarding, so the map it's really unplayable.
I must say that the battles are smooth and the framerate it's very good, so the problem it's only on the map.

@Lor Dric mainly, but any modder might find it jogs their thinking:
  I had these issues in Perisno, then pre-test "A" Warsword Conquest, and the map lag came down to 3 areas of tuning:

1) replace every instance of 
    (rest_for_hours, ":hours", 5, 0), #kill some time and coincidentally set the speed multiplier until changed
        with
          (rest_for_hours, ":hours", "$g_warsword_wait_multiplier", 0), # waiting is now scaleable.

    I'd set that multiplier at 3 for example.  Then when someone ctrl-spacebar to speed time passing the CPU doesn't have to process the 220 or so background tasks at 5x normal rate, now just 3.  For kicks and giggles let the user set it with xgm_options
from a range of 2 to 4.  I'd say this value needs to be low considering the number of parties you have on map.

2) I became concerned about parties on the map and ended adding a report to manually check if the parties on map had too many disabled, how many parties total a try_for_parties loop has to iterate through, and to count a template that I expected to find in large numbers and see if the Warband tool telling how many of those parties there were was accurate, or it there were disabled parties etc wasting bandwidth during a try_for_parties loop.
it looked like this:
Code:
   ("metrics_for_parties", [ ], "{!}Measure parties counts.",
     [
      (jump_to_menu, "mnu_metrics_for_parties1"),
      ]
     ),

# ...  sometime later in game_menus.py

  ("metrics_for_parties1", 0,
    "{s16}^{s17}",
    "none",
    [
    (assign, ":total_parties", 0),
    (assign, ":inactive", 0),

    (assign, ":count_looters", 0),
    (assign, ":count_deserters", 0),
    (assign, ":count_royal_traders", 0),
    (assign, ":inactive_royal_traders", 0),
    (assign, ":count_patrol", 0),
    
    (try_for_parties, ":party_no"), 
        (val_add, ":total_parties", 1),
    	(gt, ":party_no", "p_spawn_points_end"),
        (party_get_template_id, ":party_template", ":party_no"),

        (try_begin),
            (party_is_active,":party_no"),
            (try_begin),
                (party_slot_eq, ":party_no", slot_party_type, spt_kingdom_caravan),
                (val_add, ":count_royal_traders", 1),
            (else_try),
                (eq, ":party_template", "pt_looters"),
                (val_add, ":count_looters", 1),
            (else_try),
                (eq, ":party_template", "pt_deserters"),
                (val_add, ":count_deserters", 1),
            (else_try),
                (eq, ":party_template", "pt_patrol_party"),
                (val_add, ":count_patrol", 1),
            (try_end),
         (else_try),
            (val_add, ":inactive", 1),
            
            (try_begin),
                (party_slot_eq, ":party_no", slot_party_type, spt_kingdom_caravan),
                (val_add, ":inactive_royal_traders", 1),
            (try_end),
        (try_end),
    (try_end),

    (assign, reg3, ":total_parties"),
    (assign, reg4, ":inactive"),
    (store_num_parties_of_template, reg5, "pt_looters"),
    (assign, reg6, ":count_looters"),
    (str_store_string, s16, "@Total Parties: {reg3}   Inactive: {reg4}^Looters: {reg5}  active: {reg6}^"),

    (store_num_parties_of_template, reg3, "pt_deserters"),
    (assign, reg4, ":count_deserters"),
    (assign, reg5, ":count_royal_traders"),
    (assign, reg6, ":inactive_royal_traders"),
    (store_num_parties_of_template, reg7, "pt_patrol_party"),
    (assign, reg8, ":count_patrol"),
    (str_store_string, s17, "@Deserters: {reg3}  counted: {reg4}^Royal Traders: {reg5}  inactive: {reg6}^Patrols: {reg7}  counted: {reg8}"),
        ],
   [
    ("return", [], "Return", 
	[(jump_to_menu, "mnu_reports"),]),
]),  # close this menu

  3) then I wanted bandwidth wasting loops such as icon flip over water to be called less often.  I used 0.35 hours for my timer, to effectively cut wasted bandwidth from that ONE simple_triggers by almost 50%.
note I use the list processing system to further reduce the number of parties to examine.
Code:
  # Updating player icon in every frame         # simple_triggers number 64
  (0.35,
   [
    (try_for_parties, ":cur_party"),
        (party_is_active, ":cur_party"),    # don't waste time on disabled parties
		(party_get_current_terrain, ":terrain", ":cur_party"),
		(party_get_template_id, ":cur_template", ":cur_party"),

        (this_or_next|neq, ":cur_template", "pt_sea_traders"),
        (this_or_next|neq, ":cur_template", "pt_sea_raiders_ships"),
        (this_or_next|neq, ":cur_template", "pt_raiders_ships"),
        (             neq, ":cur_template", "pt_pirate_ships"),

        (assign, ":continue", 1),
        (try_begin),
            (eq, ":cur_template", "pt_none"),
            (party_get_icon, ":test_party_icon", ":cur_party"),
            (eq, ":test_party_icon", "icon_ship_on_land"),
            (assign, ":continue", 0),       # GS we want to exclude from the list beached player ships
        (try_end),    

        (eq, ":continue", 1),    
	(try_begin),
	    (this_or_next|eq, ":terrain",rt_bridge),
            (this_or_next|eq, ":terrain",rt_river),   # terrain type 15 isnt defined in header_terrain.py
            (eq, ":terrain",rt_water),   #  could only apply to p_main_party  (player)
    
            (call_script, "script_list_index_of", "trp_list_04", ":cur_party"),  # reg1 index, -1 not found
            (try_begin),
                (eq, reg1, -1),     # its not in the list already
                (party_get_icon, ":cur_icon", ":cur_party"),
                (party_set_icon, ":cur_party", "icon_ship"),
                (call_script, "script_list_add", "trp_list_04", ":cur_party"),  # stuff the party_id
                (call_script, "script_list_add", "trp_list_05", ":cur_icon"),   # stuff the icon
            (try_end),
        (try_end),
    (try_end),

    (call_script, "script_list_count", "trp_list_04"),
    (assign, ":list_end", reg1),
    (val_add, ":list_end", 1),
    (gt, ":list_end", 1),   # we can skip any empty list (actual length = 0)
    
    (try_for_range, ":list_index", 1, ":list_end"),
        (call_script, "script_list_at_nc", "trp_list_04", ":list_index"),
        (assign, ":cur_party", reg1),

        (try_begin),
            (neg|party_is_active, ":cur_party"),    # party must have been defeated very recently
            (call_script, "script_list_remove_at", "trp_list_04", ":list_index"),
            (call_script, "script_list_remove_at", "trp_list_05", ":list_index"),
            (val_sub, ":list_end", 1),
            (val_sub, ":list_index", 1), # because you need to test that index again next iteration...
        (else_try),
            (party_get_current_terrain, ":terrain", ":cur_party"),
            (neq, ":terrain",rt_bridge),  # 
            (neq, ":terrain",rt_river),   # terrain type 15 isnt defined in header_terrain.py
            (neq, ":terrain",rt_water),   # 

            (party_get_template_id, ":cur_template", ":cur_party"),
            (neq, ":cur_template", "pt_sea_traders"),   

            (call_script, "script_list_at_nc", "trp_list_05", ":list_index"),
            (assign, ":cur_icon", reg1),
            (party_set_icon,":cur_party",":cur_icon"),
    
            (call_script, "script_list_remove_at", "trp_list_04", ":list_index"),   # partyID
            (call_script, "script_list_remove_at", "trp_list_05", ":list_index"),   # icon
            (val_sub, ":list_end", 1),
            (val_sub, ":list_index", 1), # because you need to test that index again next iteration...
        (try_end),
    (try_end),
    ]),

list management system at https://forums.taleworlds.com/index.php/topic,341079.0.html

  This use of a list was originally intended to put the party on water into a list to check more often if it hits land, while skipping river crossings, so as to use try_for_parties less often.  In this case you could for example run the above trigger less often, say  0.7 hours, then every .35 hours check if dry land was hit only within that list, so as to react faster but go through your huge number of parties far less often, reducing apparent stutter.  The added overhead of a list manager only makes sense if we assume for example about 1 in 8 parties are on the water, at most, so if we could not check all the other parties as often we save ourselves a processing spike.  If 40% of the parties were on water, I'd reckon we're at break-even, and with more we'd suffer a net LOSS of bandwidth.  I'd especially reconsider the use of this line          (call_script, "script_list_remove_at", "trp_list_04", ":list_index"),  # partyID
and try to avoid it completely if possible, for a very big list.  A very small list (50 parties for example out of 2000) the added overhead isn't a burden.

  Optimize every try_for_parties firing every 2 hours or less.    But actually Lor Dric knows this.  I suppose I'm reviewing for any other modder...

3) battles are already smooth per the OP so actually these few tricks are probably the ones that pay the quickest.  With just tuning icon checking as above Perisno .772 was sped up by 1/3rd for .773 for overland map travel, as was Warsword Conquest for (still unreleased) patch 2.  Its proven to work for over two weeks on Warsword Rigale test, so I'm not just making up numbers.  In WC I have 1000 parties on map the first few seconds and this grows to about 2000 parties after bandits, kingdom parties, traders, and such have popped for around 1 week.  I changed the frequency of kingdom_party spawns from 1 check every hour down to 1 check every 2.31 hours, the weird size to not have it go off at the same time as all the other 1 hour and 2 hour triggers.  Picking a weird frequency reduces a standing wave in terms of smoothing a spike in CPU useage.  I suppose its sort of like using spread spectrum on a clock timer circuit.

  I haven't shared much but you're one of the few I trust, and this little bit of open discussion doesn't really hurt anyone.  You have an impressive number of parties on map; they probably need to fit into some fast lists and be less often try_for_parties  (which I use just for filling lists once and then drive the list which I assume is much much smaller, else the list overhead doesn't get profit in bandwidth.  I wouldn't remove anything from a list that was huge its almost faster to build a fresh list if its done too often.  But you'd see that.

  Well, all this you know, but its useful review for anyone else.
good luck on this, in my experience you're one of the few that would do this well.

  - GS
It's something that Lor Dric must do, or that we users must do to have a decent performance on the map ?
 
Buckethell said:
It's something that Lor Dric must do, or that we users must do to have a decent performance on the map ?

Only Lor Dric, as the source code is closed not open.
 
Buckethell said:
gsanders said:
Buckethell said:
It's something that Lor Dric must do, or that we users must do to have a decent performance on the map ?

Only Lor Dric, as the source code is closed not open.
So he's already working on it ?

  You know, if he trusted me with the source I'd do it for him.  But as it is, I generally don't ask other modders for stuff and they generally don't offer.  I happen to know Lor Dric, at least a little, and he does good work.  I expect he can do it without my kibbutzing, but he has at 4000 parties on map almost double the time spent in loops of my mods.  So he has to both slow the speed of time passing during fast moves/forced rests, and break up as many loops in the simple_triggers and triggers code as possible, while staggering those so they don't overlap when they go off. 

  When it comes down to it, Lor Dric is one of the few that pushes the envelope.  4000 parties is pushing pretty hard. 
  I expect he knows there is some lag from sheer number of parties and is trying different optimizations.  I sent him some last year but I've pushed the envelope a little more since then.  He in turn has obviously cleaned up some of the things I screwed with briefly then dropped with Curtain of Fire, and he has a pretty large mod in every way.  I think if he uses the list system and doesn't remove from huge lists one at a time but instead copies from list to list when there would be many deletions he could optimize bandwidth better; lists were suggested to try not to loop through every party very often, but instead to loop through MUCH SMALLER lists, around 400 to 600 elements deep instead of 2000 to 4000 parties at a time.  If he is checking 4000 parties on the map in say 3 or 4 different places in the timers code and those timers are all firing at once each hour that will be huge stutter on the map.  If those timer operations didn't go off exactly each hour but one was say 1.21 hours and another 1.32 hours, and another 1.55 hours so the processor peaks from each of those timers is spread out the game would feel much smoother.  Its a matter of looking at each timer and seeing if it could go off less often, go off at a fraction more than 1 hour, and so on, while looking for tricks to not have to iterate through every party or at least skip a party very quickly if it isn't matching some quick test.

  So far I've added nothing to the discussion but we're very aware of each other's work.

  - GS
 
Level 23 and the minstrels still won't teach me any poems.  They say they have taught me all they know, even though I haven't had a single one teach me anything yet. 

No biggie, though.  Just makes it a little harder to get married, but other than that, not sure of any other uses for the poems.
 
I still can't use onagers and other artillery units at all, guessing they are useless till 4.0 comes out. But still can not establish alliances with other factions at all, kinda confused about this.
 
Much as I really wanna play this mod, it's currently unplayable in terms of FPS and stability, seems I'm not the only one with the problem :sad:

Keeping an eye on it though.
 
Been playing around with being a mage.  Here is some pictures of my mage; some call him...Timm:


My favorite weapon so far:  a Flame Wave staff:


It has taken me awhile to figure out how to use the Flame Wave.  The first time I charged the enemy and cast it, my forward motion carried me into the wave, my horse fell out from under me, and the next thing I knew I fell unconscious. :oops:  I make sure I am sitting still when I throw it now.

I have also had good luck summoning goblins and Black Knights; I plan to try other summonings as I learn more.
 
I got this mod yesterday (already one of my favorites, right after Warsword Conquest :smile:) and tried playing as a mage, but I can't figure out how does magic work in Empire IV...
Is it only via staves (the only one I got was "Wound Curse" or something like that), or can you get spells in similar fashion like in Phantasy Calradia (spellbook)? The same question goes for summoning, how do you summon?
 
Downloaded beta 4. Loads well.  Saw very little lag while traveling on map. I see you have dialed back the magic; it was a bit unbalanced before ( but a lot of fun to wipe out armies with a flame wave or two from a distance!).

Here's Timm with one of his new mounts:


 
Please explain Perma Death...is that any time anyone (yourself, companions) dies in combat? If so, that kinda is a deal breaker for what looks to be an amazing mod. And it does look amazing. Also, is there any guides on the magic system?
 
adrakken said:
Please explain Perma Death...is that any time anyone (yourself, companions) dies in combat? If so, that kinda is a deal breaker for what looks to be an amazing mod. And it does look amazing. Also, is there any guides on the magic system?

I've been playing Empire III and Empire IV since the beginning and have never experienced Permadeath.  It IS a combat game, so there should be some risk; you just have to keep Permadeath in mind and manage your actions accordingly, and not take too many wild risks.  There is a Death Ward you can purchase, as well as game saves. 
 
Awesome, mod has some great depth in that case.

While playing I was only able to find options to build fortifications, perma camps and settlements, does the option to turn a settlement into a town or village come up later or is there another way to build those that is hidden? Perhaps there is a guide you can point me to so I dont slam this thread with nub questions  :fruity:
 
adrakken said:
Awesome, mod has some great depth in that case.

While playing I was only able to find options to build fortifications, perma camps and settlements, does the option to turn a settlement into a town or village come up later or is there another way to build those that is hidden? Perhaps there is a guide you can point me to so I dont slam this thread with nub questions  :fruity:

Since Empire IV is based on Empire III, you can read the board for Empire III where lots of features of the mod are discussed in the threads listed there.
 
Status
Not open for further replies.
Back
Top Bottom