Failing to change a variable's value passed into a coroutine as an argument


#1

Hi,

First of all, congrats for Skookumscript! It’s been a lot of fun to use it since I felt comfortable enough with the syntax, API bindings etc to try it here in a sandbox project I have set up in UE4. I’m really happy with its language features, design ideas etc. Specially coroutines (and being able to use _wait(xx frames or seconds) at will, to relieve gameplay code processing, and also being able to issue commands/code snippets while the game is running. This is mind blowing for iterating on the scripts, fixing it, prototyping. For me it feels like the next step in scripting for realtime stuff.
Also the way the IDE and script files are structured: separating each function in its own page. Scrolling through huge class implementation pages can be a bit boring, even with icons for collapsing code blocks. So, thumbs up again. I decided two days ago that certainly I’m gonna use skookumscript for my game. I like blueprints, its right-click searching that tries to match results is great etc, but when the graphs get too complex, its just not intuitive to browse them. Too much zooming in and out, panning to follow the execution line/flow.

Ok, enough of praising. My question:

  • I’m trying to change/update the value of a member variable (ex: “@distance_to_target”) inside of a coroutine through an argument, but it’s failing to change it. I’ve read in some answers that by default arguments are passed into methods and coroutines by reference, so I don’t understand why they’re not being changed.
    For instance:

  • I have this data member, @distance_to_target.

  • I havea coroutine called ‘brake_cable_lift’. // I removed the underscore in it here because the post tool was messing it

  • In its implementation page, it has

(Real distance_to_target, Actor destination_point)
[
distance_to_target := distance_to(destination_point)
]

  • But when I try to use @distance_to_target again, outside and after the coroutine call, but in the same page/script as the call (the script is a coroutine called “_update”, with a loop), I notice that @distance_to_target didn’t get updated.

Shouldn’t it have updated, as it is passed by reference into the coroutine?

(*I tried using a return argument, but when I put the ; before it, inside the parentheses, the Erros window in the IDe say something like “Tried to find an expression but didn’t find one”.

Any help will be greatly appreciated. I’m starting to learn the language, script some gameplay stuff to exercise (lifts, doors etc), so sorry if the question is too dumb.This text will be hidden


#2

Glad to hear that you are enjoying SkookumScript!

Is your @distance_to_target a “raw” data member? Was it created via Blueprints (raw) or via SkookumScript (not raw)?

If it is a raw data member then it is actually a function call that looks like a data member - just for convenience. Due to this, there are some limitations compared to non-raw data members - such as being able to pass it by reference. Whenever it is used it creates a brand new object so any changes to that object will not go back unless it is reassigned to the raw data member again. This raw data members should be highlighted in the IDE so they stand out more and it needs to be documented more in the manual. They can be quite handy when they work though.

Here is some additional info:

Looking at your brake_cable_lift(), could you just return the result as a primary return?

// brake_cable_lift
(Actor destination_point) Real
[
// return distance as result
// last expression is always returned from a code block
distance_to(destination_point)
]

You would call it with something like this:

!distance: brake_cable_lift(actor)

If I understand your question properly, just returning the result as above is probably best. Though if you did want to use a return argument, this is how you would go about it:

// brake_cable_lift
(Actor destination_point; Real distance_to_target)
[
// Bind `distance_to_target` to distance before routine completes
distance_to_target: distance_to(destination_point)
]

You would call it with something like:

!distance
brake_cable_lift(actor; distance)

Or declare the variable right in the return argument slot:

brake_cable_lift(actor; !distance)

You can find out more about using return arguments in the Primer in the SkookumScript online docs. This just talks about using them not actually how to put them in routines like I did above.

Good luck and please spread the word about SkookumScript!


Here are some tips for putting code in forum posts:


#3

Thanks for the reply. And for the extra examples on using return arguments.

Looking at your brake_cable_lift(), could you just return the result as a primary return?

The thing is, the coroutine is more complex than what I’ve put in the example. It has some 8 parameters and I needed it to return some 3 objects (actually, I was thinking about referenced variables in arguments being changed, as you noticed). I gave a simpler example to help illustrate.

But the info you gave me on this difference between raw data members and data members declared inside SkookumIDE is invaluable. Actually, I would create all my data members, variables inside of SkookumIDE, but I need some to be edited, fine-tuned in UE4 editor (for me and other team members that won’t be scripting).
Also I wanted some of these data members to be easily accessible to blueprints, for initial protoyping (again, other team members etc).
So, a good practice would be to declare most of my data members in SkookumIDE? Is there any workaround or trick to link the &raw data members to “clones” of those that I would rather use in SkookumIDE? Or maybe exposing these ones created in Skookum to blueprints (maybe I can setup some generic functions in blueprints to overwrite the ones exposed to UE4 editor)?

Thanks in advance, and for the quick reply!