bugBattle for Wesnoth - Bugs: bug #21776, Replays of reloaded games skip...

 
 
Show feedback again

bug #21776: Replays of reloaded games skip 'preload' event handlers

Submitted by:  SlowThinker <slowthinker>
Submitted on:  Sun 09 Mar 2014 08:43:26 PM UTC  
 
Category: BugSeverity: 3 - Normal
Priority: 5 - NormalItem Group:  None of the others
Status: NonePrivacy: Public
Assigned to: NoneOpen/Closed: Open
Release: 1.10.7Operating System: Windows XP

Add a New Comment (Rich MarkupRich Markup):
   

You are not logged in

Please log in, so followups can be emailed to you.

 

(Jump to the original submission Jump to the original submission)

Thu 24 Apr 2014 12:51:36 PM UTC, comment #18:

Correction of a sentence:

"wesnoth.synchronize_choice: Recovers a WML table that was computed on one client only or WAS STORED IN A REPLAY"

(i tried to use italic in place of capitals and failed)

SlowThinker <slowthinker>
Sun 20 Apr 2014 08:44:24 PM UTC, comment #17:

>Especialy in a mp game, a controller can also change during the game without reloading.

Inside of a mp game, the hosting player who changes the controller from/to AI can take a measure before, by a context menu.
And yes, a new event "controller_change" would help.


>> So the input must stay within turn 2.
>But i think the turin 2 event is inside turn 2?

I understand now.
I thought it worked in a start event only. I missed words "or also in every other synced event".
It seems powerful, for example it allows private (or group) diplomacy talks or an exchange of items in FFA games. The only problem is if only 2 players are talking then the other ones must wait.


>there is an option using sync_choice whcih is replay save even in 1.12 (maybe even 1.10)

I think I understand: Naturally the argument function of synchronize_choice is not called in replays, and rather the synchronized return table is used. So synchronize_choice not only
sychronizes the table among the clients (this is useful after a select event that changes the game state),
but also
sychronizes the replay with the real game (this is useful after a reload or select event that changes the game state)

(I was confused by this sentence in the wiki
"wesnoth.synchronize_choice: Recovers a WML table that was computed on one client only or was _stored_ in _a_ replay"
that probably tries to explain it but was unclear to me.
)

But I think the main problem would be to find an appropriate moment of the synchronization of was_reloaded_synced. A moveto event needn't be sufficient because the synchronization may be needed earlier.
So I would prefer to sychronize in game_events.on_event. Would it work?

>game_events.on_event is onyl mpsave (mpsave = replaysave) when the fired event is a mpsave event

Do you mean on_event is called only before mpsafe events? Or it is called also before select events and so it may cause OOS if I am not careful?
Also I am a bit confused by the term mpsafe. I expected in BfW pre-1.11.13 one must distinguish three types of events:
- select: it is fired on one client only
- attack_end: it is fired on all clients, but [message][text_input] is not synchronized
- moveto: it is fired on all clients, and [message][text_input] is synchronized
?

SlowThinker <slowthinker>
Sun 20 Apr 2014 02:07:26 AM UTC, comment #16:

PS: how do i make yellow blocks ?

Daniel <gfgtdf>
Project Member
Sun 20 Apr 2014 02:07:00 AM UTC, comment #15:

> Like the lua environment that is not saved.

Well it's hard to do so. And most likeley that won't be fixed soon.

> don't forget the save/load process doesn't lead to an identical situation, since the controller may change.

Especialy in a mp game, a controller can also change during the game without reloading. And yes making decisions dependent on current controller types might result in OOS in some cases.

> A preload event is fired sometimes, sometimes it is not.

I agree that this can be confusing

> So the input must stay within turn 2.

But i think the turin 2 event is inside turn 2?

also if you are agree with fireing on teh next moveto event like

> Hmm ... it could still work if a preload event just detected a reloaded game and then first moveto

there is an option using sync_choice whcih is replay save even in 1.12 (maybe even 1.10):
1) Choose a variable name like 'was_reloaded'
2) set 'was_reloaded' to true in preload events.
3) in moveto events do something like
[lua]
code=<<
local was_reloaded = wesnoth.synchronize_choice(
funtion()
return wesnoth.get_variable("was_reloaded");
end)
wesnoth.set_variable("was_reloaded_synced", was_reloaded)
wesnoth.set_variable("was_reloaded", false )
>>
[/lua]
4) dont use the variable 'was_reloaded' anywhere else
and you'll have a replaysave variable 'was_reloaded_synced' that contains whether there was a reload between this move and the last move.

Daniel <gfgtdf>
Project Member
Wed 16 Apr 2014 01:34:07 PM UTC, comment #14:

(I agree this is a minor cause, probably not worth to work on it. Wesnoth has much more serious problems. :) Like the lua environment that is not saved.
)

>Also becasue i currently believe that relaoding should not change the gamestate


I understand that philosophy, but the problem is the WML/lua system is far from perfect, and there are situations in which it is useful (see comment #7, the text "that come to my mind").

And from a philosophical point of view, don't forget the save/load process doesn't lead to an identical situation, since the controller may change.
An example scenario: WML may help AI to cheat

>> IMO a replay should be an exact replay.
>there are other events aswell which arent fired in the replay (select ... )

I see.
But still ... it is expected a select event won't be fired during a replay because it is not synchronized. It is natural to expect that any stuff will be replayed iff it is synchronized.
Also select events behave consistently in a replay. A preload event is fired sometimes, sometimes it is not. (The situation would be more clean if the events were distinguished, name=preload,save_and_reload )

Conquest Minus:

>which could maybe the be solved by moving all the "make some input" in the "turn 2" event. But maybe you meant player actions (move, attack) while i thought you meant right click menus, [message][option] and similar by input.

Yes, I meant [message][option]. But in turn 1 players play the game, and in turn 2 they decide whether the start is balanced enough. So the input must stay within turn 2.

SlowThinker <slowthinker>
Tue 15 Apr 2014 03:32:06 AM UTC, comment #13:

> it could still work if a preload event just detected a reloaded game and then first moveto event (or select event or wesnoth.game_events.on_event(?)) arranged a menu for a player.


that'd prevent the ui problem but still the dilaog wouldn't show up in the rplay becasue the preload events didint happen.
and select event arent mpsave, and wesnoth.game_events.on_event is onyl mpsave (mpsave = replaysave) when the fired event is a mpsave event.

> It wouldn't help me: In fact I need to 'return' from the end of turn 3 to the begining of turn 2.


hm i thought becasue you said earlier:

> In Conquest Minus, after the point of the first save and before the reload, the game continues one more turn so that the players can make some input. If the game continued (without a reload) then there would be one additional dummy turn, which would increase a natural turn numbering. This is why the game must be reloaded.

which could maybe the be solved my moving all the "make some input" in the "turn 2" event. But maybe you meant player actions (move, attack) while i thought you meant right click menus, [message][option] and similar by input.

> I object mostly from a general point a view: IMO a replay should be an exact replay.

there are other events aswell which arent fired in the replay (select events, victory events) and also there it's in the repsosibility of the addonprogrammer no not modify the gamestate too much. Think of preload event similar to select events, that what i currently do. It's not impossible to implement fireing the preload events in replays, but as long as i don't know a good scenario where that'd be useful i won't do this work (and i still didn't understand what you are tying to do). Also becasue i currently believe that relaoding should not change the gamestate, and instead behave like the original game. Because i also think that this is what most players would expect (especialy in SP).

I was thinking about a feature to 'escape' the unsycned context, during select event which should then also work during preload events, similar to ai.synced_command from which i don't know whether it's aquirable durign preload events. but i doubt that'll go into 1.12.

Daniel <gfgtdf>
Project Member
Tue 15 Apr 2014 02:20:21 AM UTC, comment #12:

>so you want to use things like [option][message] or luas sync_choice during preload events?


I was rather theoretizing.
Hmm ... it could still work if a preload event just detected a reloaded game and then first moveto event (or select event or wesnoth.game_events.on_event(?)) arranged a menu for a player.

>Idk whether it helps you wit your original problem ...


It wouldn't help me: In fact I need to 'return' from the end of turn 3 to the begining of turn 2.
(Maybe if I want to avoid a game reload then I can join two scenarios ... )

Anyway this is not a serious issue for me.
I object mostly from a general point a view: IMO a replay should be an exact replay.

SlowThinker <slowthinker>
Mon 14 Apr 2014 01:46:15 AM UTC, comment #11:

so you want to use things like [option][message] or luas sync_choice during preload events? im pretty sure that this shouldn't work Especialy because you are not allowed to (that means you sholdn't) use ui things befreo the start events.

Idk whether it helps you wit your original problem, but in 1.13 i recently implemented a feature http://wiki.wesnoth.org/LuaWML:Misc#wesnoth.synchronize_choice the third argument, to allow to show dialogs to All palyers in 'start' events (or also in every other synced event). The intention with this was to allow things like the Pick your recruits addon without loosong the extra turn which makes it incompatible to most scenarios.

Daniel <gfgtdf>
Project Member
Thu 13 Mar 2014 11:04:12 AM UTC, comment #10:

>> a savefile can serve as the starting point of the game and can offer choices
>hmm i still don't understand what you mean.


Normally players choose a scenario, set its parameters in the game lobby or in the game beginning, and play.
Similarly they could choose a savefile, a preload event would allow them to set game paramenters, and they would play.

For example Conquest Minus generates random unit spawns. If a spawn is interesting, more players might want to play it, but with different settings than the original players.
A preload event could offer players to chanhge settings.
This is doable by a context menu too, but many Wesnoth players don't know about custom menu items or don't expect it.

SlowThinker <slowthinker>
Wed 12 Mar 2014 10:54:55 PM UTC, comment #9:

> Also this bug happens with reloaded savefiles:

that bug is indeed very strange but if i am correct (im not 100% sure though) these savefiles are generated by the server, while this bug is completely localted on client side, so i doubt they are related.

> you mean "in game_events.on_load"?

no you cannot use game_events.on_load in mpgames. And even if, it would be skipped in replays too. i didnt meant you could achieve what you want with "game_events.on_save" but you can use it to keep non-constant lua varuiables consistent in savefiles. using set_variabe in on_save and get_variable and clear afterwards in preload.

> if [variables] didn't exist then this bug could be prevented in a reload event: https://gna.org/bugs/?19258

ogh it seems like saveloading in mp is seriously bugged, and i think that bug is definitely more serious than this bug ... .

> a savefile can serve as the starting point of the game and can offer choices

hmm i still don't understand what you mean.

Anonymous
Wed 12 Mar 2014 08:12:37 PM UTC, comment #8:

Also this bug happens with reloaded savefiles:
https://gna.org/bugs/?19603

SlowThinker <slowthinker>
Wed 12 Mar 2014 08:10:53 PM UTC, comment #7:

> but in the game the lua variables are deleted during reload, in the replay that doesnt happen. And the prelaod events are normaly executed to compensate that.


Oh, I didn't know that.

>thats also possible with the current implementation. save variables in wesnoth.game_events.on_save and restore them in preload events.


you mean "in game_events.on_load"?
game_events.on_load is not skipped in replays like preload events?
and wiki confuses me - game_events.on_load is called also when a game starts or only when a sevefile is loaded?

>i don't think fireing preload events again would cause problems though.


If you don't delete the Lua environment concurrently then it can cause problems.
- An initialization of a Lua structure in a preload event can use 'if something == nil then'
- In a non-preload event one can check whether the game has been reloaded by testing a Lua variable

> i think throwing them away just to rebuild it in a replay would waste of cputime


IMHO to save cpu time by complicating things and asking for problems is not a good idea.
I would say it even if I didn't see any concrete issues, but here are some more that come to my mind:

- a savefile can serve as the starting point of the game and can offer choices
- a specific side controller may be required to play the game or may determine a mode of the game
- sometimes a preload event is a way how to bypass a Wesnoth bug:
-- in past a status of disallow_end_turn was not saved in a savefile
-- if [variables] didn't exist then this bug could be prevented in a reload event: https://gna.org/bugs/?19258

_____________________________________________________________
Conquest Minus:

>hm i still dont understand how do you put the input you gained during that one turn in the save of the first turn. do you use [set_global_variable] ?


The players' input is not a part of the game. In the input players can veto the game. So the input determines whether the game will continue (and will be reloaded) or a new game will start.
I need players do the input simultaneously, without any knowledge of the input of the other player - this is why a Wesnoth chat cannot be used.

SlowThinker <slowthinker>
Wed 12 Mar 2014 02:22:27 AM UTC, comment #6:

> In Conquest Minus, after the point of the first save and before the reload, the game continues one more turn so that the players can make some input. If the game continued (without a reload) then there would be one additional dummy turn, which would increase a natural turn numbering. This is why the game must be reloaded.


hm i still dont understand how do you put the input you gained during that one turn in the save of the first turn. do you use [set_global_variable] ?

> Lua variables are not saved. Imagine you transform a table into a WML container (this transformation would be somewhat opposite to wesnoth.get_variable), so that it is saved. Then a reload event loads this table from the WML container.
> This way you can work a full-featured way with Lua tables, and you are not limited to WML tables only.


thats also possible with the current implementation. save variables in wesnoth.game_events.on_save and restore them in preload events.

and in the last post i meant preload not prestart.

Anonymous
Wed 12 Mar 2014 02:10:54 AM UTC, comment #5:

> If the real game had no problem and the replay is equal to the real game then the replay must be problem-free too, musn't it?


but in the game the lua variables are deleted during reload, in the replay that doesnt happen. And the prelaod events are normaly executed to compensate that. So the replay will never be equal to the game because the lua variables arent deleted, and i think throwing them away just to rebuild it in a replay would waste of cputime.

i don't think fireing prestart events again would cause problems though.

Anonymous
Wed 12 Mar 2014 12:46:13 AM UTC, comment #4:

I named it a bug because I expected the replay should replay the game exactly how it went in reality.

> people would have to check wether their envoronment is already loaded in every preload event then.


I cannot imagine how any problem could happen then.
If the real game had no problem and the replay is equal to the real game then the replay must be problem-free too, musn't it?

_____________________________
Problems in Conquest Minus
This is a minor problem for Conquest Minus. I created a walkaround, which is not perfect from several points of view, but it is sufficient.

>is there a special reason why they have to reload a game to agree and not pressing a right click menu button to do so?


In Conquest Minus, after the point of the first save and before the reload, the game continues one more turn so that the players can make some input. If the game continued (without a reload) then there would be one additional dummy turn, which would increase a natural turn numbering. This is why the game must be reloaded.

____________________________
Other problems
There are other scenarios in which you expect a reload event not only loads constants (Lua constants), that couldn't be saved, but does a real job: example:

Lua variables are not saved. Imagine you transform a table into a WML container (this transformation would be somewhat opposite to wesnoth.get_variable), so that it is saved. Then a reload event loads this table from the WML container.
This way you can work a full-featured way with Lua tables, and you are not limited to WML tables only.

SlowThinker <slowthinker>
Tue 11 Mar 2014 10:38:36 PM UTC, comment #3:

so you realy want to have reloading an influence on the players game?

thats currently not realy supported so i'd rather call that a feature request than a bug.

People currently use preload events to initialize lua envornemts, and load data stored in gamesave (lua-)events and doing that twice in replays might lead to errors. Still i implementing this would be possible but people would have to check wether their envoronment is already loaded in every preload event then.

is there a special reason why they have to reload a game to agree and not pressing a right click menu button to do so?

Anonymous
Tue 11 Mar 2014 09:34:01 PM UTC, comment #2:

There is no OOS in the game. An OOS may occur in the replay though, because the replay is not "synchronized" with the real game.

This is because preload events are skipped in the replay.
In the example below, after the 'preload' event runs 2nd time, the variable 'reloaded_game' has a different value in the replay and in the game.

(To be very concrete, in Conquest Minus I allow a mode where players can estimate their spawns while their units have zero movepoints. If they agree to play then they reload a game, the add-on understands the game has been reloaded (see the variable reloaded_game in the code below), and their units get full movepoints back.)

SlowThinker <slowthinker>
Tue 11 Mar 2014 08:20:21 PM UTC, comment #1:

the preload event event is normaly meant to intilialize things that are not prsitent in savefiles. For instance Lua environments, wml variables ARE persitent thats why you get OOS errors, it would be good if you gave us an example where you get an error in real context (meaning what are you trying to do).

note that normaly people rely on the fact that the preload event is only fired once after the game is loaded and therefore their lua environments can only be inialized once.

Anonymous
Sun 09 Mar 2014 08:43:26 PM UTC, original submission:

Imagine this situation:

1. a game is started
2. 'preload' events are fired
3. the game continues
4. the game is saved and reloaded
5. 'preload' events are fired 2nd time
6. the game continues
7. the game is saved and replayed

The replay will skip point 5. Therefore OOS may occur during the replay.

An example:

The code bellow will behave this way:
in a game: it will write 'reloaded_game=no' before the game reload and 'reloaded_game=yes' after the reload
in a replay:
it will always write 'reloaded_game=no'

SlowThinker <slowthinker>

 

(Note: upload size limit is set to 1024 kB, after insertion of the required escape characters.)

Attach File(s):
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -unavailable- added by gfgtdf (Posted a comment)
  • -unavailable- added by slowthinker (Submitted the item)
  •  

    Do you think this task is very important?
    If so, you can click here to add your encouragement to it.
    This task has 0 encouragements so far.

    Only logged-in users can vote.

     

    Please enter the title of George Orwell's famous dystopian book (it's a date):

     

     

    No Changes Have Been Made to This Item
    Show feedback again

    Back to the top


    Powered by Savane 3.1-cleanup