How to script interaction between the player and entities

Discussion in 'Starbound Modding' started by lonesurvivor, Dec 11, 2013.

Thread Status:
Not open for further replies.
  1. lonesurvivor

    lonesurvivor Big Damn Hero

    The problem got fixed now. Script calls from tech to entities are now possible, so this method is no longer required.

    I got really frustrated by the fact that it is impossible to access entitie (monster/npc) objects from a self made tech lua script. I tried everything, for example:

    - getting it from a world function by passing the ID (not implemented/ no viable function)
    - adding it to a global table like math (doesn't work)
    - using the callScript parameter on world.monsterQuery (game crashed with access violation error)

    So nothing seems to work to transfer data from the player to the monsters, using a tech script. I don't know if there are custom scriptable use items (I found none in the game), but i think with them it would not work either. The reason is, that the two script are obviously running in completely different environments, so there is no way of an interaction right now, as long as the host process doesn't allow it. The only thing you can do is getting their entityIds, their Name and stuff, and that's not what I want.

    But: As you can see in the games premade scripts, for example the penguinufo behavior.lua script, in general it works. NPC's can interact with other NPC's and monsters, because they seem to be in the same scripting environment. So I tried to exploit that. And it works. I want to share this with you, if you want to make a Mech with custom scripted monster fighting, here you go:



    You can spawn NPC's with

    Code:
    world.spawnNpc(position, species, npctype, level, unknownInt, unknownOptions)
    There are three variable you can transmit information with: position (x and y, float/double precision) and level (integer). With them you need to handle all the stuff you want to "say" to the entity. And the position argument is needed to tell your dummy npc where it should do the entityQuery. So in most cases you have only the level as an freely usable argument. However, if you are smart you can spawn multiple npc' and store the additional information in math (i didn't try this, but all npcs are in the same lua environment, so it should work).

    The NPC works only as a dummy to call an entityQuery with the callScript argument:
    Code:
    world.entityQuery(position, radius, { callScript = "functionname", callScriptArgs = arguments)
    And the NPC can do it, because it's in the same lua environment. Just put it in the init() function and it will work.

    So this way you can define your own custom function, for example, in groundMonster.lua, which then is getting called by the NPC, which is getting spawned by the player tech. => Goal achieved!


    Two words to the dummy NPC: It needs do despawn immediately after spawning, because it is only useful in spawning. After that, you have no way to access it anymore from your tech script (like all the entities). So for transfering constant data to the monsters you need to spawn a lot of them, and you don't want to stay them in your game.
    I achieved this by setting the health of my dummy NPC to 0 in the npctype file. This way it will die immediately after its init() function has been called. That's exactly what we want. You also want it to be invisible, because there is no reason to see it.


    If you want to see exactly how it works, take a look at my telekinesis mod.


    This whole workaround seems quite demanding to the hardware due to all that spawning. But it works surprisingly well. I spawn an NPC everytime the update function is called in my telekinesistech.lua to update the position of my mouse, and it doesn't lag at all. And I'm working on a laptop (a fast one, though). The only lag that sometimes occurs comes from the monsterQuery calls in the npc, which can be a bit slow if there are a lot of monster in the area and the radius is large. But in general it works fine. And it should work with objects, too. But i didn't try it yet.


    I hope this helps you out. Happy coding ;)
     
    Last edited: Dec 19, 2013
  2. Phlosioneer

    Phlosioneer Pangalactic Porcupine

    Very clever solution!
     
    lonesurvivor likes this.
  3. Razey

    Razey The One Who Writes (Starbound)

    Pretty neat guide, this.
     
    glitchdetector and Phlosioneer like this.
  4. Supergeek

    Supergeek Cosmic Narwhal

    A clever solution. Hopefully the devs give us a better solution for inter-sandbox communication. My modding has been very frustrating due to the inability to communicate between entity, tech, and object easily. I pretty much gave up for now.
     
  5. lonesurvivor

    lonesurvivor Big Damn Hero

    I am convinced that they will improve this at some point, they just might have to do a lot of other stuff at the moment. WIthout a better lua API, modding is very limited and you can't really do much in terms of game mechanics and complexer mods.
     
  6. madtulip

    madtulip Phantasmal Quasar

    im currently searching for a way to pass data from the shipworld to the planet world. i was thinking about storing information inside the player entity. do you think youre approach could work here? my brain is a bit to flushed atm to go thrue youre code, sorry for that. ill do that later though. maybe you already have a qiuck shot about that?
     
  7. lonesurvivor

    lonesurvivor Big Damn Hero

    I don'T think this will work. You can store data in the tech object when activating a tech, but the script will be reinitialized when teleportingfrom the ship to the planet, so it will be gone then. But this has not very much to do this my solution to the communication between entities ;)

    Anyway, the problem got fixed with the last patch, so my method is obsolete now.
     
  8. Westeller

    Westeller Space Penguin Leader

    Techs can communicate with entities, now?
    Still, I don't think objects can? So an object > entity communication might use your old method?
     
  9. madtulip

    madtulip Phantasmal Quasar

    from a object .lua you can
    Code:
    world.callScriptedEntity(EntityId, "test_function")
    you need to define "test_function" in the target. that at least works if the entity is an object. currently triing to figure out if i can put such functions in the player entity. well we are highjacking the thread, sorry.
     
  10. Westeller

    Westeller Space Penguin Leader

    Hmmmm? Well I never tried defining a custom function, but I tried calling functions that already existed in groundMonster.lua and got nowhere. The log always came back telling me I was trying to call a nil function. Maybe I'd messed up somewhere.

    Oh, now wait, "if the entity is an object"? I meant for an object interacting with a monster.
     
  11. lonesurvivor

    lonesurvivor Big Damn Hero

    exactly. works with objects, npc's, monsters. Should work with player too, at least if you are having a tech enabled (there is no general player script running as far as I know)
     
  12. madtulip

    madtulip Phantasmal Quasar

    i didnt do anything with .techs so far. maybe i should look there. so a .tech that is active allows me to have a set of lua functions that can manipulate the player object? how would i adress that tech ? can i just get the entityID of the player and call test_function if that is defined in the .lua belonging to the active tech ?
     
  13. mrflippy

    mrflippy Lucky Number 13

    I haven't had any luck running anything based on a player id. I'm not sure if there's a way to get the id of a tech. My tests with the query functions haven't turned up much.
     
Thread Status:
Not open for further replies.

Share This Page