Phodex Games Posted August 31, 2016 Share Posted August 31, 2016 Hi, I have a small problem. I am currently working on a spellsystem. For this I created a "Spell Effects Library.lua" file, which contains any possible effect that a spell could cast to easily access the effects. I have two types of spells. Spells on target and on self. The "on self" spells get casted in the player script: import "Scripts/Spell Effects Library.lua" . . . if KeyHit then self:CastSpell(something) end The script for the Library looks like this: function Script:CastSpell(something) . . . end So far so good. For the "on target" kind of spells the shooten projectile casts the effect on hit. Those code is just for visualization: import "Scripts/Spell Effects Library.lua" . . . if hit then self:CastSpell(something) end So If I shoot a projectile now and it hits its target it says "attempt to call method 'CastEffect' (a nil value)". BUT if I delete the import line at the player script it works just fine. It does not seem to be possible to import the same script into two other scripts? So could you help me please? How to manage this? Quote Link to comment Share on other sites More sharing options...
Genebris Posted August 31, 2016 Share Posted August 31, 2016 Yes, it's not possible that way. I had the same question here: http://www.leadwerks.com/werkspace/topic/10616-importing-one-script-into-two-different-scripts/ Take a look how default AnimationManager script functions. You can do the same thing. Or maybe just use global table with all your effects, this will be simpler actually. And you won't need to import any scripts anywhere. Quote Link to comment Share on other sites More sharing options...
Rick Posted August 31, 2016 Share Posted August 31, 2016 There really are 2 kinds of scripts. There are Leadwerks scripts and user scripts. Leadwerks scripts are the ones that have: function Script: in them. These are the scripts you attach to entities on the editor or in code at runtime via Entity:SetScript. The user scripts is something like Gene mentions in the AnimationManager script. It's like this because Josh removed the ability to attach multiple Leadwerks scripts to an entity (it's a sensitive subject for some). So now if you want to share some functionality between multiple Leadwerks scripts you either copy/paste the code (gross) or you create a "class" script like AnimationManager and put your code in there. Then in your Leadwerks script you import it, create and instance of the class, and call functions on it. There are other options but this is the basics of object oriented programming which Leadwerks sort of uses in various places so it's easier to recommend that way because you have examples of it in Leadwerks. Would just be a lot easier if we could attach multiple Leadwerks scripts to entities wouldn't it There really are 2 kinds of scripts. There are Leadwerks scripts and user scripts. Leadwerks scripts are the ones that have: function Script: in them. These are the scripts you attach to entities on the editor or in code at runtime via Entity:SetScript. The user scripts is something like Gene mentions in the AnimationManager script. It's like this because Josh removed the ability to attach multiple Leadwerks scripts to an entity (it's a sensitive subject for some). So now if you want to share some functionality between multiple Leadwerks scripts you either copy/paste the code (gross) or you create a "class" script like AnimationManager and put your code in there. Then in your Leadwerks script you import it, create and instance of the class, and call functions on it. There are other options but this is the basics of object oriented programming which Leadwerks sort of uses in various places so it's easier to recommend that way because you have examples of it in Leadwerks. Would just be a lot easier if we could attach multiple Leadwerks scripts to entities wouldn't it Quote Link to comment Share on other sites More sharing options...
Phodex Games Posted August 31, 2016 Author Share Posted August 31, 2016 Ok thank you guys. Will try that out. @Rick: Yes I always wondered why you cant attach more then one script to an entity? Well you can work around it but sometimes it is really annoying. Quote Link to comment Share on other sites More sharing options...
Genebris Posted August 31, 2016 Share Posted August 31, 2016 It simple, just make this script and import this into main.lua at the very beginning: spellEffects={} function spellEffects:CastSpell(something) . . . end Then you can call spellEffects:CastSpell() anywhere in your game and you don't need multiple scripts or importing. Quote Link to comment Share on other sites More sharing options...
Rick Posted September 1, 2016 Share Posted September 1, 2016 Globals always seem like the simple solution until the majority of you app uses a lot of them and your code becomes so fragile and unmanageable. I'd be very careful with using many globals and if you do go back and try to refactor them out. 1 Quote Link to comment Share on other sites More sharing options...
gamecreator Posted September 1, 2016 Share Posted September 1, 2016 While I'm not making a AAA game, I've never had issues using globals as long as I've kept them organized. Quote Link to comment Share on other sites More sharing options...
Phodex Games Posted September 3, 2016 Author Share Posted September 3, 2016 I think the way Genebris mentioned is very cool. I need to create a globale for the "Animimation Manager-like" classes anyways. As gamecreator says if you keep them organized it should work fine. What other method would you suggest Rick? Quote Link to comment Share on other sites More sharing options...
Josh Posted September 3, 2016 Share Posted September 3, 2016 The reason we use one script per entity is so that there is always a single unambiguous function or member for the value you are looking for. During development I tried both approaches, and found that when using multiple scripts you basically end up breaking off every script variable that multiple scripts access into its own script. Then you need a unique prefix to identify that script, so instead of just calling script.health you have to call script.HealthManager.health, or some such thing. When we have a 1:1 entity/script relationship it is easy to check if a function exists and call it if it does. Many scripts tend to have similar functions like TakeDamage() which results in scripts magically working together, even when they weren't developed to work in unison. With multiple scripts you either have an extra namespace to guess to get the right function, so scripts tend to stop spontaneously working together as they did before.. You can also have problems with multiple scripts containing the same function or member, and not knowing which should be considered the "real" value. After having worked with both of these approaches during development of Leadwerks 3.0 I am confident the single-script approach was the right way to go. This design decision will not be changed. For your question above, I believe you can do this: Import "CastSpell.lua" function Script:Start() self.CastSpell = CastSpell end function Script:Update() self:CastSpell()--passes self in as first argument end CastSpell.lua: function CastSpell(script) script.DoSomething()--"script" is like "self" end Lua is very flexible and there are probably several ways of handling this: https://www.lua.org/pil/16.html 2 Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Josh Posted September 3, 2016 Share Posted September 3, 2016 In fact, this actually works: --Create a table and add a value local mytable = {} mytable.value = "Hello" --Create a global table function local dummytable = {} function dummytable:SomeFunction() print(self.value) end --Assign the function from one table to another mytable.SomeFunction = dummytable.SomeFunction --Call the function mytable:SomeFunction() Even better. This uses the secret global table (standard Lua thing) in which all variables are stored so you don't even need the dummy table: --Create a table and add a value local mytable = {} mytable.value = "Hello" --Create a global table function function _G:SomeFunction() print(self.value) end --Assign the function from one table to another mytable.SomeFunction = _G.SomeFunction --Call the function mytable:SomeFunction() I think the above is a good solution to the situations where you want some amount of code reuse across scripts. 2 Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Phodex Games Posted September 3, 2016 Author Share Posted September 3, 2016 That was really informative, thank you for the very detailed description . I always love to learn new stuff to sweeten and shorten my code. And I understand the thing about the two scripts per entity. I know that as a user of a software you often don't think as far as the developers did and for me this feature isnt that kind of a big deal. There are other and also very cool ways to get the same effect. Can't wait to try out the newly learnt method ^^ Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.