Modding Help [Nightly] world.callScriptedEntity in Status Effect Script Assistance

Discussion in 'Starbound Modding' started by Claith, Nov 20, 2014.

  1. Claith

    Claith Big Damn Hero

    I'm posting in hopes of resolving this quicker than if I just kept fussing about it myself as I want to get the first version of this project released by the weekend.

    I'm trying to apply a custom status effect (the same as Glow, just different value) to nearby entities. Monsters and npcs for right now. The code I'm using to do this is:

    Code:
    function afflictTargets( )
        local entityIds = world.entityQuery(mcontroller.position(), self.targetRange, { includedTypes = {"monster"} })--potentialTargets()
      
        for i, entityId in ipairs(entityIds) do
            if validTarget(entityId) then
                world.logInfo( "mutagenLightWalkerSkill.lua::afflictTargets() : Valid Target Found" )
                world.callScriptedEntity( monsterId, "mutagenApplyLightWalkerEffect" )
            end
        end
    end
    I commented out the "potentialTargets()" code for the short term, as I'm just seeing if I can get it to work on the monsters first. The range is 500, so there shouldn't be an issue with that, and the function "mutagenApplyLightWalkerEffect" I had it setup as a global in this file, but that didn't work, so I instead added the script (below) to each of the monster types using the patch system.

    Patch:
    Code:
    [
        { "op" : "add", "path" : "/baseParameters/scripts/-", "value" : "/scripts/mutagenNPC.lua" }
    ]
    Script (mutagenNPC.lua):
    Code:
    function mutagenApplyLightWalkerEffect()
        status.applyEphemeralEffect( "mutagenLightWalkerEffect" )
    end

    Now the error comes from the callScriptedEntities line and needs to be resolved some how is:
    Code:
    Error: Exception while invoking lua function 'update'. (LuaException) [string "/stats/effects/mutagenlightwalkerskill/mutage..."]:107: (VariantException) intify called on improper type null
      VariantException::VariantException(string)
      intify(Variant)
      LuaBindings::WorldEntityCallbacks::callScriptedEntity(World*, List<Variant, deque<Variant, allocator<Variant> > >)
      _Function_handler<Variant (List<Variant, deque<Variant, allocator<Variant> > >), _Bind<Variant (*(World*, <1>))(World*, List<Variant, deque<Variant, allocator<Variant> > >)> >::(_Any_data, List<Variant, deque<Variant, allocator<Variant> > >)
      LuaCallbacks::invokeFunction(unsigned int, List<Variant, deque<Variant, allocator<Variant> > >)
      Lua::LuaEngineImpl::invokeCallbackClosure(lua_State*)
      lua_getinfo
      1AFF5F50
      20DC1450
      20DC1420
      1AFF5F50
    
      StarException::StarException(String)
      Lua::handleError(lua_State*)
      Lua::LuaEngineImpl::doInvoke(int, String, List<Variant, deque<Variant, allocator<Variant> > >, bool)
      Lua::LuaContextImpl::invoke(String, List<Variant, deque<Variant, allocator<Variant> > >)
      LuaBaseComponent::invoke(String, List<Variant, deque<Variant, allocator<Variant> > >)
      Maybe<Variant> LuaBaseComponent::invokeArgs<float>(String, float)
      LuaUpdatableComponent<LuaWorldComponent<LuaBaseComponent> >::update(function<void ()>, Maybe<List<Variant, deque<Variant, allocator<Variant> > >>)
      LuaActorMovementComponent<LuaWorldComponent<LuaBaseComponent> >::update(function<void ()>, Maybe<List<Variant, deque<Variant, allocator<Variant> > >>)
      StatusController::tickMaster()
      Player::tickMaster()
      WorldClient::update()
      UniverseClient::update()
      ClientApplication::updateRunning()
      ClientApplication::update()
      StarApplicationBase::run()
      _SDL_main
      _console_main
    I am under the understanding that the function should work correctly as I have it. If I could make it into a global function that works, that would be great, so I wouldn't have to apply a patch to every single monster / npc out there. I haven't had any use for globals in LUA yet, and when I tried before the results weren't correct, so I avoided it in my script.
     
  2. Hey uh... buddy?

    Code:
    world.callScriptedEntity( monsterId, "mutagenApplyLightWalkerEffect" )
    Where did you define monsterId? Pretty sure you want to use entityId there...

    Also there is a world.monsterQuery() You should be using that instead of entityQuery
     
    Claith likes this.
  3. Claith

    Claith Big Damn Hero

    Well, talk about falling on my face. I copied code from the standing turret and modified it for my use. I can't believe I didn't see that.

    Now, if I could get some feedback on the use of globals, I'll be golden. I really don't like having to apply a patch for every .monstertype .npctype config file.
     
  4. If you elaborate on what you want I could try and help, but I can tell you now you are going to have to apply a patch to each monster to get that script added to them if that is what you are asking. When I hear Globals I think global variables - dont know if thats what you are talking about.
     
  5. Claith

    Claith Big Damn Hero

    It doesn't give that error any more obviously, but now my character is a walking plague and everything dies around me. That isn't the intended effect, so I've got to sort that out. Fun though, for the short term.

    Working in a vacuum is some what of a hazard. Thank you for the extra set of eyes.
     
  6. Any time. When I feel that frustrated with code I get up, go grab a cup of tea and lay on my bed for about 10 mins then go back. Sometimes you just get too frustrated to think straight and overlook simple things like that. I know I do it all the time! Should give that a shot next time. Just walk away for a few minutes and come back.
     
    Claith likes this.
  7. Claith

    Claith Big Damn Hero

    The death problem is because I had "applyEphemeralEffect" instead of "addEphemeralEffect" I didn't think a bad function call would cause things to die. Anyways, it works now. I just need to roughly balance and then I'll release this large bundle of scripts and status effects. I do hope you take an interest in it. Only the first version. Next is an interface to address not knowing anything about the effects.
     
    The | Suit likes this.
  8. Peelz

    Peelz Giant Laser Beams

    Haha, that's pretty funny that the game's way of handling a bad function call is to kill the monsters instead! Better than crashing though :D
     
  9. Claith

    Claith Big Damn Hero

    As a follow up to this same project, but not specifically this problem, I have another problem. For the past day or two, I've been getting an error in the player_primary.lua when the player character gets hit. It is in the applyDamageRequest( ) function, line 8. I made a character without the mod to see if this is my fault or something from the daily updates. Seems it is my fault. What made me look at this error, that is some how indirectly caused by me, is that my project works a lot on resources, which include health and breath. Energy is working correctly as far as I can tell. A good half of the project (as it stands) relies on the health resource, so I can't go further.

    I want to get assistance, since I have no idea where to look for this problem. The player gets hit and doesn't lose health. The player goes in the water and doesn't lose breath. I can't have that. Now the problem is, that I can't just give a snippet of code to work with. A lot of these files are interconnected in a way, where I will have to post a sizable chunk of my code. That being said, I'm wondering if I can get assistance with the project, to sort this out (I'm serious about the weekend deadline here for release), but I will have to release the mod into the mod database and subsequently those assisting will have to download it from there.
     
  10. If you could pastebin it I could take a look when I get the chance.
     
  11. Claith

    Claith Big Damn Hero

    I don't think that is feasible right now for me.

    Tearing the mod apart erasing chunks at a time doesn't seem to help, so it may be a structural issue caused by changes in the nightly. I've had to adjust previously, because some fields in the player.config were removed before. Unpacking the latest and going to go digging to figure out what, if anything changed, then move from there. I'll post it, bugged to hell or not tomorrow.
     
  12. Claith

    Claith Big Damn Hero

    I narrowed the cause down to a single line. It is the inclusion of a script into the player.config's primaryScriptSources field.

    Code:
    { "op" : "add", "path" : "/statusControllerSettings/primaryScriptSources/-", "value" : "/scripts/mutagen.lua" }
    The other parts of the .patch file don't seem to affect the issue. I stripped everything out of the script in my earlier attempts to debug it, so now mutagen.lua is now:
    Code:
    function init()
        -- Lesson learned. You can't apply a status effect here during creation. It must be done post-creation
        --world.logInfo( "mutagen.lua::init : Setup = %f, Version = %f", status.statusProperty( "mutagenSetup" ), status.statusProperty( "mutagenVersion" ) )
        script.setUpdateDelta(600) -- slow down the needless updating. Don't seem to be able to force a stop.
    end
    
    -- Can not add status effects during initialization, so update(dt) is required
    function update(dt)
        --world.logInfo( "mutagen.lua::update(dt) : entrance : Setup = %f", status.resource( "mutagenSetup" ) )
    
      
        --world.logInfo( "mutagen.lua::update(dt) : exit : Setup = %f", status.statusProperty( "mutagenSetup" ) )
    end
    
    -- There isn't a default function to clean up, so trying to stop the updating myself here.
    function uninit()
        --world.logInfo( "mutagen.lua::uninit : mutagenSetup = %f", status.statusProperty( "mutagenSetup" ) )
        --status.setStatusProperty( "mutagenSetup", 3)
    end
    
    Nothing there but comments, and the updateDelta inclusion or exclusion didn't affect anything. This is a key piece of code I made for applying status effects during character creation, if my post history is searched, it would be there in a generalized form. Now, I have no idea why this is causing the player_primary.lua to not work correctly or how exactly the player's health and breath doesn't update (loaded a character with lower than max breath meter, and it stayed at the same value).

    I'm trying to decide if this is an oversight in the scripting system, or if there is anything I can do. The only thing I can think of, is to change from a status effect based script system to a tech based one. I did not and do not want to use a tech slot, though. That would be a last resort that I could force.

    -----------------

    Did some more testing, by alternating the above functions. uninit() doesn't change a thing thankfully, but the existance of init() and update(dt) are the problems. If I removed both, I did not have the issue. If I removed only init(), then I did not have a change in breath, but I was able to get hit once and it did not spawn any error messages. Since I gutted the code out of the functions, the error message changed from the line 8 of player_primary.lua to line 58, talking about the lastYVelocity being nil.

    All this frustration makes me wish I could patch onto the player_primary.lua. If I want this mod to work correctly, I may have to just overwrite it for every version. That is a bit more commitment than I want out of a mod project.


    -------------

    I checked, and it works with applying the status effect in the player_primary.lua script instead of in mine. Just not the form I want. It will have to do for the time being I guess. I will do some testing and some balancing to get rid of the extreme variations then release it in 12-24 hours. Yes, I consider this to be an important mod. Like my Gems mod (which I haven't looked at in months) I consider each project to be novel, and I want to release this ahead of the curve, as I'm surprised another hasn't stolen the concept yet considering I didn't work on it for a two week period.
     
    Last edited: Nov 22, 2014
  13. Claith

    Claith Big Damn Hero

    For anyone following this thread still, I posted it here

    I'm going to work in rewriting it from an object oriented approach to a monolithic one, and see if I can save on calls to help speed up the script(s). Currently after playing in single player for an extended period of time (5-10 minutes, seems to vary - also going left seems worse than going right in the world for some reason) the server slows down and eventually stops responding. I don't know if these issues occurred before I switched to overwriting the player_primary.lua script to solve the above problem. I don't think it did, but I didn't test that long. There were strange instances that could count, though. The processing amount is considerably higher than without the mod, which is why I'm taking this approach first to address the issue.

    Feel free to poke around it. I just released it now, as after about two weeks of work on it, over four weeks, I wanted to claim credit as the original. This should also explain why I want certain aspects of the status effect system extended.
     
  14. AstralGhost

    AstralGhost Pangalactic Porcupine

    This probably doesn't help much, but.....
    You're worrying far too much about creating artificial deadlines for yourself because you seem to believe it's important to get a mod out before anyone else creates a similar one.

    I would suggest not to do that anymore. Pushing those sort of deadlines just means you're rushing through your code and not taking your time to fix errors and resolve issues. Instead your releasing a haphazardly done mod that doesn't work properly.

    What do you think is more important in these two cases?
    A.) Releasing a mod with a brand new idea, even if that means the mod doesn't work right.
    B.) Releasing a mod that works right, even if that means it's not a completely new idea.

    To be honest, the reason this worries me is because most of the modern game industry is going the route of pushing deadlines to release new games, at the cost of it's stability. Tons of new games all have major issues at release that must be patched out. Some never even get the patching support because the Publishers pull the developers from supporting the game because they already got their money, leaving the game itself high-and-dry.
    It's bad practice - and it is destroying the industry.

    As modders, the one and only advantage we really have is that we aren't on any sort of deadlines or teams focused on delivering on specific promises. We basically do what we want, when we want... And that means having the chance to deliver a working product the first time around. Not many other developers get that chance. So, this is a friendly suggestion: Embrace this opportunity. Solve the issues you have and worry less about the arbitrary release-dates or other people with your idea. I promise you that if you do it this way, your idea will still come out looking unique.

    Don't believe me? Look at the most popular mods out there right now. Were any of them ever released in a state that wasn't working very well? :)

    That said, I apologize for not helping you find what is causing your errors. I get lost in the explanation every time I read it.
     
    Claith likes this.
  15. So what exactly is not working at this time? Apologies. I have not been receiving proper notifications upon a response.

    Edit: So I already posted this, then shortly deleted it because I thought I was not thinking straight and was wrong. Looked back at it and I was actually right all along.

    The reason you are having problems with the inclusion of the PrimaryScriptSources is because you are actually overwriting the original functions!

    So when the game loads the first script, here is what gets assigned to init():
    Code:
    function init()
      self.lastYVelocity = 0
      self.fallDistance = 0
      self.hitInvulnerabilityTime = 0
    
      local ouchNoise = status.statusProperty("ouchNoise")
      if ouchNoise then
        animator.setSoundPool("ouch", {ouchNoise})
      end
    end
    So everything works fine and dandy. Then when your script comes along, the game sees this:
    Code:
    function init()
        -- Lesson learned. You can't apply a status effect here during creation. It must be done post-creation
        world.logInfo( "mutagen.lua::init : Setup = %f, Version = %f", status.statusProperty( "mutagenSetup" ), status.statusProperty( "mutagenVersion" ) )
        script.setUpdateDelta(600) -- slow down the needless updating. Don't seem to be able to force a stop.
    end
    and OVERWRITES the original init() function above. This is why you are having errors. You are not aware of this change and therefore probbaly have no clue why the hell things are breaking.

    Lua does not allow you to make functions of the same name and just have each one call! It will get overwritten if re-defined. If you want to run BOTH of the above, you must place a wrapper and grab the old one first like so:
    Code:
    -- MUTAGEN.LUA FILE --
    local oldInit = init -- We "capture" the old function and save it as a local variable for later use
    local oldUpdate = update
    local oldUninit = uninit
    
    function init()
        oldInit() -- SEE WHAT I DID HERE? We called the old one first, and now can call our custom stuff.
        -- Lesson learned. You can't apply a status effect here during creation. It must be done post-creation
        world.logInfo( "mutagen.lua::init : Setup = %f, Version = %f", status.statusProperty( "mutagenSetup" ), status.statusProperty( "mutagenVersion" ) )
        script.setUpdateDelta(600) -- slow down the needless updating. Don't seem to be able to force a stop.
    end
    
    -- Can not add status effects during initialization, so update(dt) is required
    function update(dt)
        oldUpdate(dt)
        --world.logInfo( "mutagen.lua::update(dt) : entrance : Setup = %f", status.resource( "mutagenSetup" ) )
        if status.statusProperty( "mutagenSetup" ) == 0 then
            status.setStatusProperty( "mutagenSetup", 1) -- in reservation of possible other uses, set to 1 for now
            status.addPersistentEffect( "mutagen", "mutagenRPG" )
        end
      
        --world.logInfo( "mutagen.lua::update(dt) : exit : Setup = %f", status.statusProperty( "mutagenSetup" ) )
    end
    
    -- There isn't a default function to clean up, so trying to stop the updating myself here.
    function uninit()
        oldUninit()
        --world.logInfo( "mutagen.lua::uninit : mutagenSetup = %f", status.statusProperty( "mutagenSetup" ) )
        --status.setStatusProperty( "mutagenSetup", 3)
    end
    

    So now your stuff will work without having to change the original player_primary.lua and will be much more compatable than simply overwriting the entire script itself.

    Keep in mind that the script order MATTERS. Since you are adding your script source to the END of the array to load them, your custom script will be loaded AFTER the player_primary.lua. If you added your script to the BEGINNING of the array, your custom script will be overwritten by the default stuff and it would look as though you had made no changes.

    The code I posted above should work as is with your patch. This will fix your issue. :)
     
    Last edited: Nov 26, 2014
    Claith likes this.
  16. Claith

    Claith Big Damn Hero

    I already have a new version nearly done. I corrected that above in the player_primary.lua, as they updated that and I caught that crash.

    I have a new problem right now, where the render fps slowly drops instead of the server eventually not responding. Going to sort that issue out soon. I hope by tomorrow evening.

    As for the artificial deadline, I put that for myself to motivate myself. I had worked on it, up to that point for about two weeks, with a two week break in the middle, as I had other things I idly did (such as a lot of reading). I currently have a monolithic script that removes nearly all the calls like status.statusProperty( "..." ), and uses self.whateverthepropertynameis now. Still trying to organize things to make updating easier, but I had to draw a line, and I had to violate a lot of the OOP design philosophy that has been pounded into me for the past.. 10 years or so?

    I'm not going to read the fixes right now, I'll do that when I get to working on it tomorrow morning. I'm already stopping for the day. Thank you both for the replies, and I hope to give a more proper response later.
     
  17. Claith

    Claith Big Damn Hero

    I did not know I could do that with lua. I'm learning the scripting language as I'm working on this mod. Specifically, I had thought that my functions were in a different scope, so they shouldn't overwrite the others. I know I can't call vec2.add( ) in mine, but it is used in player_primary.lua, so I just appropriated that code and dropped it into my file.

    I haven't had much luck or really use with globals, so I didn't know or think of using lua in such a manner. My above post is some what incorrect, so ignore the first line. I haven't used things like function pointers in c++ either aside from virtual calls, then again I've been using c# wanting to use c++ only things for years, like unions and void pointers.

    When it comes to the render fps right now, I didn't have this problem till recently, so I'm once again going to remove chunks and test it, as I don't really have a good version control system. I just keep the last major form or release.[DOUBLEPOST=1417007420][/DOUBLEPOST]Having a bit of a problem with the stored functions, but doing some research to sort that out, something about the dt parameter not working and all that (Just me being foolish - sorted out). Ignoring that for now, it seems like I can redesign my code to be implemented like player_primary.lua, instead of as a status effect. I really wish I knew this when I started, but then I wouldn't be learning. Just a copy and paste job to address that design choice thankfully. I wish I could give another round of "likes." I'm wondering if I could have made this system even earlier when I first thought of making it, about a year ago, instead of waiting for the status effect system.
     
    Last edited: Nov 26, 2014
  18. Think of Starbound's script array the way you would with including .h files. When you include the header, everything gets combined into one file for the compiler to use - same thing happens in lua. So if you defined 2 of the same functions then the compiler would complain in the case of C-Languages. Here, they get overwritten because they are allowed to. A minor, yet VERY useful feature - even though it could cause problems like this.

    Anything that does not have the world "local" in front of it will be in the global scope ( assuming it is not pre-defined in a local scope - AKA trying to change a local variable)

    We have a little "Intro to Lua" post here if you wish to take a look and brush up on anything you still find confusing. We have been meaning to write more for a while, but have been short on time lately.

    In regards to the FPS, I did not take a very deep look at all of the code but make sure you arent doing any expensive loops or iterating through a poorly managed table that for some reason keeps growing (Using different variables as Keys each time you store something). However, that said it might not even be your fault! This is nightly and things may be happening through no fault of your own. Just check your code, run through it in your head as to what is possibly happening in best and worst case, and then go from there. If it seems like its your fault then fix it... if not tell me and Ill have a look.
     
    Claith likes this.
  19. Claith

    Claith Big Damn Hero

    I'm pushing more of the resources towards using memory over computation. The updated code isn't upload yet, and I'll manage it myself. I did something which caused this around the time I tried to reimplement animations (level up animations, and the one for evasion ). It was working well before, averaging around 43 fps or so, on my oldish system. Don't bother looking at the code right now. If I'm stumped, I'll upload the newest version and reply with it asking for help. Should be easier to debug than what is currently uploaded. The most computational aspect of the code, is the same code used to find a position for a random blink tech. Everything else is much simpler.
     
  20. AstralGhost

    AstralGhost Pangalactic Porcupine

    Setting up deadlines for yourself is all well and good, but just don't let it motivate you to rush or give up on projects either. There should be a balance.

    You should give yourself goal dates, but obviously move those dates back if you can't realistically achieve them.
    From my perspective: Goals are good, deadlines are bad.

    Project management is a pretty big thing in the programming world. Many programmers find themselves completely lost trying to manage projects correctly and often either produce rushed products or simply delay their products indefinitely.
    I like to point out to those people, when I can, that they should simply just relax and allow their projects to develop more fluidly, taking one step at a time. In my experience, at least, this always leads to better code. :)
    I don't much like seeing people rush themselves with programming for no real reason. I saw a lot of that from people back in school and the amount of their errors just made me LOL. Those errors tend to be really hard to fix without rewriting, too. So inevitably it just becomes a waste of time to produce that sort of code. Since you stated you're rewriting much of these things, I'm sure you are experiencing this symptom first-hand.

    And again I apologize for not helping with the errors and bigger problems. I post from a very different computer than the one I use for Starbound. I haven't had any free time to get on that computer lately.
     
    Claith likes this.

Share This Page