Running long codes makes Papyrus looks slow...

Post » Wed Jun 20, 2012 10:05 pm

Justin, not sure if this helps, but couldn't you isolate the IsEquipped (weapon) form, then do a small loop just for that item and remove item either at one shot -1 (or -2) to see if it works, or use a
if !IsEquipped, then if count > than 1 or 2 (dual wield), remove by 1 until left with just 1 or 2?

not sure if I just made sense.. Sorry.

From some stuff I've done, I think that http://www.creationkit.com/DropObject_-_ObjectReference would first look through the inventory for unequipped items, while http://www.creationkit.com/RemoveItem_-_ObjectReference seems to have a preference for equipped items.
User avatar
Skivs
 
Posts: 3550
Joined: Sat Dec 01, 2007 10:06 pm

Post » Wed Jun 20, 2012 5:00 pm

We can have a Formlist of Formlists? Nice! I was so disappointed when I found that we couldn't have nested arrays.
An FLST can contain any form, but the constituent FLSTs' members aren't seen if checking such an FLST of FLSTs, unfortunately. Still useful for nested While loops...
@Justin, in the inner loop where at least one item has been found to be equipped, it will probably speed it up if you could filter out the equipped items from the full list and do a bulk RemoveItem() on most of the weapons on the list in one go. Even if you had to use an empty tempformlist just used for this purpose. It's probably the UI having to be updated (and blinking) that is causes most of the lag.

Watching this to see how 'intelligent' the removeItems is for equipped weapons. Fingers crossed it does leave equipped items in hand if poss.
With FNV I had to avoid all equipped/hotkeyed/worn stuff as it was pretty random.
Tried 'Player.RemoveItem(BagOfHoldingSortStavesFLST, Player.GetItemCount(BagOfHoldingSortStavesFLST) - 2, True, Self)' with two staves equipped and all were removed including the two that were equipped. ={

Inner loop: Might be worth a shot, but I think I'll make more specific, smaller FLSTs to add to BagOfHoldingSortWeaponsAllFLST and simultaneously add more sorting options, then all should happen faster. Thankfully, the player can go about their business until the sorting is done, but with every weapon in the game, it took about 3-5 minutes (made coffee, came back and it was still going at it) to finish and right/left hand weapons were still equipped. The bag blinking is inconsequential as it takes just as long if doing it without the inventory/container UI up.
Justin, not sure if this helps, but couldn't you isolate the IsEquipped (weapon) form, then do a small loop just for that item and remove item either at one shot -1 (or -2) to see if it works, or use a
if !IsEquipped, then if count > than 1 or 2 (dual wield), remove by 1 until left with just 1 or 2?

not sure if I just made sense.. Sorry.
From some stuff I've done, I think that http://www.creationkit.com/DropObject_-_ObjectReference would first look through the inventory for unequipped items, while http://www.creationkit.com/RemoveItem_-_ObjectReference seems to have a preference for equipped items.
I'm gonna keep trying, but so far even if subtracting the number of equipped members from aiCount, RemoveItem() took them all.

Carp: "If you pass in a form list, it will remove aiCount of each item in the form list from the container. If there isn't aiCount of a particular item in the container, it will remove all of them" (Wiki).
User avatar
Poetic Vice
 
Posts: 3440
Joined: Wed Oct 31, 2007 8:19 pm

Post » Wed Jun 20, 2012 7:40 am

Carp: "If you pass in a form list, it will remove aiCount of each item in the form list from the container. If there isn't aiCount of a particular item in the container, it will remove all of them" (Wiki).

I tried a RemoveItem with a form list without specifying aiCount, and for me, the script would not compile. It would not even default to one.. let alone all.

oh, I mean do a small loop just for the equipped weapon that can be isolated.. then do a !IsEquipped on just that item. removeitem with aiCount 1 if you need to do this. Heh, can this even be scripted?
User avatar
Invasion's
 
Posts: 3546
Joined: Fri Aug 18, 2006 6:09 pm

Post » Wed Jun 20, 2012 1:26 pm

Wouldn't doing a check for !isEquipped be better applied straight to the removeItem line? That way each item is removed if not equipped, and doesn't create yet another logic loop to jump through each time.

Nesting the loops may help too, as others have suggested... but I'm not sure if it's because the formlist you check to is so big, or if the logic loops are causing slowdown somehow. While loops keep running as fast as they can (from what I understand), so if you can sit and watch one item be removed in slow-mo, then it sounds like there are fundamental changes you need to make. I tried comparing a while loop with an onUpdate event (set to 0.033) and they are about the same - though the onUpdate caches itself if a previous one hasn't finished running; they quickly stack up so even after the script 'ends' it takes a while to resolve, as in it keeps running until all the Update events have completed.. even if return is called. This doesn't really apply to you, I was just trying to show the speed differences... and that it isn't the game-engine itself causing the slow-down. My point is that if I can move an object fairly reliably at 30 fps, then removing objects from inventory shouldn't take much longer.

As far as the speed of Papyrus, it IS a little slower than Obliv's scripting... noticed when trying to smoothly move objects in real-time (I know 'translateTo' helps fix studder, but that comes with it's own issues and consequences). Part of it is because it's thread-driven... it runs if there are available threads and waits if there aren't any. This makes getting my ship to sail with real-time Player controls VERY difficult. The amount of lag you're getting.. maybe it's caused by multiple instances of the script running simultaneously? (as in, your code is set to fire on a certain event, which is triggered inside itself or repetitively)
User avatar
Lloyd Muldowney
 
Posts: 3497
Joined: Wed May 23, 2007 2:08 pm

Post » Wed Jun 20, 2012 2:34 pm


Performance
There are a few things to keep in mind when keeping things like performance in mind. With the old scripting language, writing inefficient script would eventually bog down the framerate of the game. In the new language, each script gets an allotted amount of processing time. After it uses up that processing time, the script will pause until it's allowed to have more processing time. This processing time is measured by function calls and logic done by the scripting language. You're much more likely to bog down all the scripts in the game then the game's actual framerate with a poorly-written script.

Timing
With the new language being fully multithreaded, timing is not quite as reliable as it was with the previous system. Previously, a script could say "I want to do this immediately," and the governing system would have no choice but to agree. A script in the new language can say "I want to do this immediately," and the script manager will essentially tell the script to take a ticket and wait in line. Telling a script to wait for 0.5 seconds really means that the script will wait for 0.5 seconds plus the time it takes for the script to get its number called. This amount of time is usually quite small, but it could have an impact on scripts where timing needs to be very precise.


http://www.creationkit.com/Differences_from_Previous_Scripting#Functionality_Changes
User avatar
lillian luna
 
Posts: 3432
Joined: Thu Aug 31, 2006 9:43 pm

Post » Wed Jun 20, 2012 5:04 pm

Fully multi-threaded yet fully unable to acquire all of my available system threads. Seriously, not all of us are restricted to 2-4 cores. What am I to do with the other 8 other than to run several virtual machines and convert movies in seconds. Why couldn't they scale the thread count based on the system? Give us a little ini config and be like HEY PAPYRUS, I GOT ANOTHER 8 CORES, DEAL WITH IT.
User avatar
Josee Leach
 
Posts: 3371
Joined: Tue Dec 26, 2006 10:50 pm

Post » Wed Jun 20, 2012 1:21 pm

Tried 'Player.RemoveItem(BagOfHoldingSortStavesFLST, Player.GetItemCount(BagOfHoldingSortStavesFLST) - 2, True, Self)' with two staves equipped and all were removed including the two that were equipped. ={

...

I'm gonna keep trying, but so far even if subtracting the number of equipped members from aiCount, RemoveItem() took them all.

So I tried out two scripts, one using RemoveItem and one using DropObject.

RemoveItem:

Spoiler
Scriptname fg109TestMEScript extends ActiveMagicEffect  Weapon property IronDagger autoEvent OnEffectStart(Actor akTarget, Actor akCaster)    int Count = akCaster.GetItemCount(IronDagger)    if (akCaster.IsEquipped(IronDagger))        if (akCaster.GetEquippedWeapon() == IronDagger)            Count -= 1        endif        if (akCaster.GetEquippedWeapon(True) == IronDagger)            Count -= 1        endif    endif    while (Count > 0)        Count -= 1        akCaster.RemoveItem(IronDagger, 1, true, akTarget)    endwhile    akCaster.AddItem(IronDagger, 10) ;for testing purposes    Debug.Notification("Complete")EndEvent

DropObject:

Spoiler
Scriptname fg109TestMEScript extends ActiveMagicEffect  Weapon property IronDagger autoEvent OnEffectStart(Actor akTarget, Actor akCaster)    int Count = akCaster.GetItemCount(IronDagger)    if (akCaster.IsEquipped(IronDagger))        if (akCaster.GetEquippedWeapon() == IronDagger)            Count -= 1        endif        if (akCaster.GetEquippedWeapon(True) == IronDagger)            Count -= 1        endif    endif    ObjectReference DroppedObject    while (Count > 0)        Count -= 1        DroppedObject = akCaster.DropObject(IronDagger, 1)        while !(DroppedObject.Is3DLoaded())            Utility.Wait(0.1)        endwhile        DroppedObject.Activate(akTarget)    endwhile    akCaster.AddItem(IronDagger, 10) ;for testing purposes    Debug.Notification("Complete")EndEvent

When testing the first one, it would take equipped weapons as well. When I was dual wielding, it took the right one. Then next cast it took the left one.

The second one worked correctly, and my equipped weapons stayed equipped. Lydia (whom I was casting this on) drew her sword a couple dozen times though and I could see my dropped daggers.

I'm going to go update the wiki with what I said earlier about the two functions now.
User avatar
priscillaaa
 
Posts: 3309
Joined: Sat Dec 30, 2006 8:22 pm

Post » Wed Jun 20, 2012 5:22 pm

Cool findings, RandomNoob, and thanks for sharing :)
User avatar
Beulah Bell
 
Posts: 3372
Joined: Thu Nov 23, 2006 7:08 pm

Post » Wed Jun 20, 2012 1:54 pm

Fully multi-threaded yet fully unable to acquire all of my available system threads. Seriously, not all of us are restricted to 2-4 cores. What am I to do with the other 8 other than to run several virtual machines and convert movies in seconds. Why couldn't they scale the thread count based on the system? Give us a little ini config and be like HEY PAPYRUS, I GOT ANOTHER 8 CORES, DEAL WITH IT.
Because that's a very hard problem to solve and the extra cores/threads aren't needed anyway. So in conclusion you get a lot of work for virtual no benefit.
User avatar
Russell Davies
 
Posts: 3429
Joined: Wed Nov 07, 2007 5:01 am

Previous

Return to V - Skyrim