B
BlackAura
Guest
Ok, long question. I'm rebuilding a project of mine from the ground up. I'm designing a system where all game world objects can interact with one another. Therefore, there's a kind of hierarchy of variables needed for each quality of an object. I'm trying to do this using scripts with as little repetition as possible so when I change a couple universal scripts, nearly all objects are affected.
for example:
is an object collectible? if so does it go to inventory?
is an object carryable? if so can it be thrown? is it heavy to lift?
does an object emit light? if so, where? what color? radius? sprite? cast shadows? etc etc etc.
You see, I can create variables to describe all of these aspects. however, you can see that more fundamental "parent" variables would need subcategories of variables, and if that more fundamental variable is false (like if the object does not cast light with the lighting engine) then I've created a ton of "sub-variables" that just take up memory.
My original solution was this. Every object has a big block of initialization code. (I'll post this for an example.) Then, I would edit this block to define almost any object in the game. This would be so virtually all objects can share a universal logical system and I could mix and match the behavioral dna if you will of any object. A simple parent and child object system is not enough. I've tried. I run into situations where I want an object with the qualities of various parents and to be checked for when either parent is checked for by other objects. To avoid creating a bunch of instance variables each specialized object would have no use of, I thought to use local variables for all variables that would only be used with certain objects, then call a script that would turn the local variables into instance variables if their "parent" variable was set to true. (this script would additionally create more specialized variables.) However, I wasn't thinking and forgot that a script cannot read the local variables in the same event calling it.
Well, this is frustrating. Could I pass local variables into the script with arguments? Absolutely, that's the point of arguments. But here's the problem. I have like... 30 local variables. far more than the 16 argument limitation.
I could just move the (turn relevant local variables into instance variables) script's code into the create event, but then if there's a modification I want to make, i no longer can modify a script and have to manually edit all my objects. Not going to happen, and completely destroys the point of having this kind of hierarchical, universal variable system. However I need all my objects to share a ton of code as objects will be endlessly reading each other's code and interacting with each other so I need to use scripts to ensure darn-near perfect interactive behavior using strict naming conventions and matching variable names throughout.
Here are my two ideas.
1: use instance variables from the start. is there a downside to having like 50 variables in every object, when each object only uses a handful of them? I thought "oh hey, is there a way to free/delete instance variables if I know for sure I won't use them like I can free a surface or data structure?" It doesn't appear so.
2: my only possible workaround. Create a ton of global variables to act like arguments, to get around the 16 argument limitation. for example. create something like a global.arg at the beginning of the game, then in my code basically do this:
global.arg[0]=var
global.arg[1]=var
global.arg[2]=var
global.arg[3]=var
customscript()
and the customscript will reference that global array instead of the built in argument[0-15] variables.
My question is this. What's the more efficient solution? Am I missing something that would be a lot more elegant?
EDIT: Third idea. Place the script's code into the parent's create code (I have a parent object called OBancestor_obj. it is essentially the parent of all parents.), then in all create events, have this initialization block run, then at the end call an event_inherited()? will the local variables from the child objects continue into the code coming in from the parent object unlike it would if that code were coming from a script?
Here's an example of that initialization code.
This is the code I wanted to run after to "clean up" my variable usage. I had this in a script but for some reason totally forgot about local variable scopes when using scripts. as you can see it does a little more than just that.
for example:
is an object collectible? if so does it go to inventory?
is an object carryable? if so can it be thrown? is it heavy to lift?
does an object emit light? if so, where? what color? radius? sprite? cast shadows? etc etc etc.
You see, I can create variables to describe all of these aspects. however, you can see that more fundamental "parent" variables would need subcategories of variables, and if that more fundamental variable is false (like if the object does not cast light with the lighting engine) then I've created a ton of "sub-variables" that just take up memory.
My original solution was this. Every object has a big block of initialization code. (I'll post this for an example.) Then, I would edit this block to define almost any object in the game. This would be so virtually all objects can share a universal logical system and I could mix and match the behavioral dna if you will of any object. A simple parent and child object system is not enough. I've tried. I run into situations where I want an object with the qualities of various parents and to be checked for when either parent is checked for by other objects. To avoid creating a bunch of instance variables each specialized object would have no use of, I thought to use local variables for all variables that would only be used with certain objects, then call a script that would turn the local variables into instance variables if their "parent" variable was set to true. (this script would additionally create more specialized variables.) However, I wasn't thinking and forgot that a script cannot read the local variables in the same event calling it.
Well, this is frustrating. Could I pass local variables into the script with arguments? Absolutely, that's the point of arguments. But here's the problem. I have like... 30 local variables. far more than the 16 argument limitation.
I could just move the (turn relevant local variables into instance variables) script's code into the create event, but then if there's a modification I want to make, i no longer can modify a script and have to manually edit all my objects. Not going to happen, and completely destroys the point of having this kind of hierarchical, universal variable system. However I need all my objects to share a ton of code as objects will be endlessly reading each other's code and interacting with each other so I need to use scripts to ensure darn-near perfect interactive behavior using strict naming conventions and matching variable names throughout.
Here are my two ideas.
1: use instance variables from the start. is there a downside to having like 50 variables in every object, when each object only uses a handful of them? I thought "oh hey, is there a way to free/delete instance variables if I know for sure I won't use them like I can free a surface or data structure?" It doesn't appear so.
2: my only possible workaround. Create a ton of global variables to act like arguments, to get around the 16 argument limitation. for example. create something like a global.arg at the beginning of the game, then in my code basically do this:
global.arg[0]=var
global.arg[1]=var
global.arg[2]=var
global.arg[3]=var
customscript()
and the customscript will reference that global array instead of the built in argument[0-15] variables.
My question is this. What's the more efficient solution? Am I missing something that would be a lot more elegant?
EDIT: Third idea. Place the script's code into the parent's create code (I have a parent object called OBancestor_obj. it is essentially the parent of all parents.), then in all create events, have this initialization block run, then at the end call an event_inherited()? will the local variables from the child objects continue into the code coming in from the parent object unlike it would if that code were coming from a script?
Here's an example of that initialization code.
Code:
//Init Universal Variables: Main
xv=x //x origin. can be different from object's x position but usually isn't.
yv=y //y origin. can be different from object's x position but usually isn't.
xspeed=0 //
yspeed=0 //
mobile=1 //if object can change position.
var i_physical=1 //if object interacts with solids.
var i_mask=mask_index //mask of object. must be set here and not in object properties.
var i_grav=1 //gravitational factor. 1:normal
var i_rollable=1 //if object rolls when moved
var i_topple=1 //if object is bottom-heavy and balances self.
var i_breakable=0 //if object is broken by being thrown.
var i_weight=16 //weight of object, controls how wind, water, etc affect it.
//Init Universal Variables: Material Properties
material=Material.mat_metal //material of object. 0:null|1:particle|2:organic|3:stone|4:metal|5:wood|6:grass|7:sand|8:snow|9:ice|10:waterbody|11:waterbodyelement|12:ghost
mat_solid=0 //if object is a solid.
mat_buoyant=1 //if object floats in water. 0:null|1:alwaysfloats|2:canbesunken
mat_burnable=0 //if object can be lit on fire.
mat_shockable=1 //if object can conduct electricity.
mat_freezable=0 //if object can be frozen in ice.
mat_blowable=1 //if object can be blown by the wind.
mat_wettable=1 //if object can get wet.
//Init Universal Variables: Interactivity
carriable=1 //if object can be picked up.
collectable=0 //if object can be collected.
container=1 //if object can contain another object.
var i_inst_contain=-1 //handle for contained object.
//Init Universal Variables: HP and DP
hazardous=0 //if object can deal damage.
var i_dp=0 //damage points (amount of dealt damage).
destructable=0 //if object can be destroyed
var i_respawn=0 //if object creates respawner object upon destruction
var i_hp=100 //health points (resistance to recieved damage)
var i_hp_max=i_hp //maximum hp.
var i_vv_iframe=0 //invincibility frames.
var i_damage_beam=1 //factor by which damage to object is multiplied. 0:invulnerable -- 1:normal vulnerability
var i_damage_bomb=1 //factor by which damage to object is multiplied. 0:invulnerable -- 1:normal vulnerability
var i_damage_burn=1 //factor by which damage to object is multiplied. 0:invulnerable -- 1:normal vulnerability
var i_damage_shock=1 //factor by which damage to object is multiplied. 0:invulnerable -- 1:normal vulnerability
var i_damage_freeze=1 //factor by which damage to object is multiplied. 0:invulnerable -- 1:normal vulnerability
var i_damage_wet=1 //factor by which damage to object is multiplied. 0:invulnerable -- 1:normal vulnerability
var i_damage_blade=1 //factor by which damage to object is multiplied. 0:invulnerable -- 1:normal vulnerability
var i_damage_lantern=1 //factor by which damage to object is multiplied. 0:invulnerable -- 1:normal vulnerability
//Init Universal Variables: Lightcast
lightcast=0
var i_spr_lightcast=-1
var i_ff_lightcast=0
var i_xv_lightcast=x
var i_yv_lightcast=y
var i_xx_lightcast=1
var i_yy_lightcast=1
var i_rr_lightcast=0
var i_cc_lightcast=-1
var i_aa_lightcast=1
This is the code I wanted to run after to "clean up" my variable usage. I had this in a script but for some reason totally forgot about local variable scopes when using scripts. as you can see it does a little more than just that.
Code:
//Create Instance Variables From Local Variables
if mobile=1
{
physical=i_physical
mask=i_mask
if physical=1
{
grounded=0
slope=0
weight=i_weight
waterlevel=0
submerged=0
rollable=i_rollable
breakable=i_breakable
grav=i_grav
if rollable=1 {topple=i_topple rr_roll=0 rs_roll=0 vv_rollsettle=0}
//event notifiers.
event_bounce=0
//universal sound timers
tt_snd_lap=0
}
}
if mat_buoyant=1
{sv_buo=0 ss_buo=0 vv_waterfill=0}
if pausable=1 paused=0
if mat_burnable=1
{vv_burn=0 vd_burn=0}
if mat_shockable=1
{vv_shock=0 vd_shock=0}
if mat_freezable=1
{vv_freeze=0 vd_freeze=0}
if mat_wettable=1
{vv_wet=0 vd_wet=0}
if container=1
inst_contain=i_inst_contain
if carriable=1
carry=0
if hazardous=1
dp=i_dp
if destructable=1
{
respawn=i_respawn
hp=i_hp
hm_max=i_hp_max
vv_hp=0
vv_iframe=i_vv_iframe
damage_beam=i_damage_beam
damage_bomb=i_damage_bomb
damage_burn=i_damage_burn
damage_shock=i_damage_shock
damage_freeze=i_damage_freeze
damage_wet=i_damage_wet
damage_blade=i_damage_blade
damage_lantern=i_damage_lantern
}
if lightcast=1
{
spr_lightcast=i_spr_lightcast
ff_lightcast=i_ff_lightcast
xv_lightcast=i_xv_lightcast
yv_lightcast=i_yv_lightcast
xx_lightcast=i_xx_lightcast
yy_lightcast=i_yy_lightcast
rr_lightcast=i_rr_lightcast
cc_lightcast=i_cc_lightcast
aa_lightcast=i_aa_lightcast
}
Last edited by a moderator: