Bubb13 / EEex

An executable extender for Beamdog's Enhanced Edition of the Infinity Engine
50 stars 7 forks source link

Multiplayer sync issue? #37

Open Doomathon opened 4 years ago

Doomathon commented 4 years ago

Background

Found while running EEex alpha 8.6, and using the "Party XP for killing creatures distributed individually" component of EET Tweaks.

For reference, said component patches creatures in an install as follows:

COPY_EXISTING_REGEXP GLOB ~.+\.CRE$~ ~override~
    PATCH_IF (NOT ~%SOURCE_RES%~ STR_EQ ~CHARBASE~) BEGIN
        READ_LONG 0x14 "xp"
        PATCH_IF xp > 1 BEGIN
            LPF ADD_CRE_EFFECT
                INT_VAR
                opcode = 67 //Summon creature
                target = 1 //Self
                parameter2 = 2 //Allegiance: From CRE file
                timing = 1 //Instant/Permanent until death
                STR_VAR
                resource = ~K#CRXP~
            END
        END
    END
BUT_ONLY

The summoned creature has a simple script attached:

IF
  True()
THEN
  RESPONSE #100
    ActionOverride(LastSummonerOf(Myself),ApplySpellRES("K#CRXP",Myself))
    DestroySelf()
END

And finally, the applied spell triggers the following Lua function

function K4_CREXP(effectData, creatureData)
    EEex_LuaObject = EEex_ReadDword(creatureData + 0x34)
    C:Eval('ChangeStat(EEex_LuaObject,XPVALUE,' .. math.max(math.floor(EEex_GetActorStat(EEex_LuaObject, 43) / 6 * Infinity_GetNumCharacters()), 1) .. ',SET)')
end

Issue description

I and a friend installed the component in question, and started playing a multiplayer game. The exp reward from creatures was as expected (divided by 6, then multiplied by the number of characters in the party) ONLY when characters controlled by the host player killed enemies. When a character controlled by a client killed an enemy, the exp reward was the full exp reward defined in the enemy .cre file.

Possible explanation

In general, it seems that the game only uses the Host player's instance of the game for retrieving certain variables (such as the exp reward for killing a creature, as in this case), and changes made only on a client player's instance of the game are totally ignored by the game. The obvious seeming solution would be to ensure all scripts that edit a creature's stats or other variables in this way are run on the server instance, which the game engine is entirely capable of syncing to client players on its own, but I don't know how easy that would be to implement.