#Best practices for setting script properties

1 messages · Page 1 of 1 (latest)

quiet veldt
#

Hi, new to using VScript, but I have experience scripting with other game engines. In Unity, when attaching a script to a GameObject, we can assign values to various properties on the object. This way, we don't have to hardcode the values within the script, allowing us to re-use the script for several instances within the level, each with slightly different values. Is there an equivalent in Hammer, or a best practice for setting constants or references to objects for logic_script to access?

For some background, I am working on a surf map where the player must shoot multiple targets while surfing to have the end gate appear. In reality, the player just gets teleported to the same spot they are at in an identical room that has the end gate in it, making it seem as if the end gate appeared, example attached. I'd like to re-use this script for multiple rooms with a different number of targets, and a different offset the player needs to be moved to teleport. Ideally, I can configure these values in the Hammer editor.

My current workaround is to have a lookup table within my .nut script that houses the total number of targets required for each stage, as well as the offset needed to teleport into the identical room. The breakable objects then additionally send their stage ID within the function called so the script knows how many targets need to be shot and where to teleport to. While this works, it has the drawback that the script must be modified for each new level/stage, which makes it less friendly to share with other mappers. Is there an alternative for storing this data elsewhere that I am missing?

rancid vault
#

no the csgo/vscript scripting implementation is not at all like a GameObject/ECS style approach

#

and was really not made to do what you are saying

#

now that being said, there are workarounds

#

I think your current approach is good, just having a big table, given the limitations of vscript

#

but if you want to basically simulate an entity having a specific value type, you can use an entity that has the ability to store that value and a vscript function exists to retrieve it

#

for example you could store a string value in the targetname field of an entity, and then retrieve the value with entityhandle.GetName()

#

this works especially well if you basically only use a certain entity class for this purpose

#

because then you can just iterate on all of them, or store all of their references in an array programmatically

quiet veldt
#

I was tempted to do a split on the name for the stage ID, but encoding the same XYZ offset on each of the targets (the player can shoot them out-of-order) seemed overkill.

rancid vault
#

its only overkill if you're fine with the "giant table" approach, IMO

#

but otherwise it is a viable alternative if you want it to be pretty map-agnostic/less hardcoded

quiet veldt
#

Oh I see

rancid vault
#

because yeah you could just encode multiple values separated by underscores and read the information back as needed

quiet veldt
#

I can put the offset on the logic_script instead of the targets

rancid vault
#

I'll say if you are basically using it informationally you may want to attach it to another entity so that you organize stuff

#

by that I mean, if you do these scripts on, let's say for example, info_landmark, then you know that any entity with the class info_landmark contains your script and it's name has encoded information in the string

#

if I'm understanding you right

#

but it really doesn't matter, just might be nicer for organizational purposes, and easier to iterate over/get in vscript

quiet veldt
#

I'm using references between the func_breakable that houses the targets and a logic_script that houses the script, though I suspect under the hood that it's just a name lookup.

Going with the table might be more appealing if I can find a way to split it out into another .nut. That way, each level can have a separate table, but all re-use the same script.

rancid vault
#

there's a basically includefile line you can add, but I'd have to look at the reference, I don't remember the name of the top of my head

quiet veldt
#

Ah, I think I saw that somewhere. That does need to be hardcoded though right? Or can the name of the file be dynamically set?

rancid vault
#

the wiki says its just a string input so i mean

#

might work dynamically since this is all done at script runtime. I would assume as much

quiet veldt
#

Sweet. Can you link me where you found that? I'm a bit lost in the number of tabs I have open lol

sage pond
#

alternatively, another approach would be to use dynamic entities instead of teleporting the player

#

you have func_brush, prop_dynamic and triggers can all be enabled/disabled at will

#

so just increment a var when a player shoots a target, when the var equals the total number of targets for the arena (can do this with a lookup array or lookup table), then just enable the final end stage trigger and the brush or prop

#

99% of the time you'll find mappers working mainly inside one master logic_script, and just do everything in there instead of bouncing around between many different entities

#
targetsPerArena <-
[
    2,
    4,
    9,
    etc...
];

currentArena <- 0;
targetsHit <- 0;

// fired from target's IO when you shoot the target with RunScriptCode
function ShootTarget()
{
    caller.Disable() //disable target once shot
    targetsHit++;
    if (targetsHit == targetsPerArena[currentArena])
    {
        EntFire("EndTrigger_" + currentArena, "enable"); // enable end trigger
        EntFire("DoorFrameProp_" + currentArena, "enable"); // enable doorframe
    }
}

// fired from trigger's IO OnStartTouch
function EnteredEndTrigger
{
    currentArena++;
}```
something as simple as this
quiet veldt
#

My assumption is that the logic_script executes server-side, and shares a single instance across all clients (i.e., client predicted but still server authoritative).

Is this the case? If so, if there are multiple players at different stages of their runs present on the server, they can end up influencing what geometry appears for one another, giving a competitive advantage (or if there are enough players, causes complete chaos) for runners that start slightly earlier than their counterparts.

sage pond
#

yep, the example i gave would only work in single player

#

or rather, it would only require one player to change the state of the entities, which would also change for everyone else on the server

#

i dont think its possible to enable/disable entities only for the client