Skookumscript performance


#1

Hi I am new to this well my question is how does skookumscript perform in relation to ue4 blueprints, lua,c#/java and c++…i really do love the Language wasnt sure about the [] but it does feel very logical and makes it somewhat easier to type


#2

Thanks for your interest in SkookumScript! SkookumScript outperforms Blueprints and it outperforms Lua by quite a large margin. We have not compared it to C# or Java but would expect a very favorable comparison as well. SkookumScript has been used on several major game projects and is performance and memory optimized to the highest industry standards. Conan (@Noolarch) and me (Markus - @GreatGuru) , creators of SkookumScript, are both each 20+ year industry veterans having coaxed the last of performance out of a many engine system in our careers. As an example, when Sleeping Dogs, a major triple A game title, underwent critical performance optimizations during its development, they found that SkookumScript didn’t even show in the profile (meaning its time consumption was so low that was found way down in the function list sorted by cycle count).

Fundamentally, well-written C++ will be of course faster than any executed scripting language, but in practice SkookumScript (which itself is written in C++) can beat naive C++ in performance due to its ability to easily time slice operations (meaning code doesn’t run every frame but only every few frames).

The language syntax is different from many you may come across though this is through much research and use on large teams. The workflow gains with :sk: can be breathtaking. You can do a tremendous number of interesting tasks in very few lines of code - or even in a single line. This in particular is the advantage of SkookumScript.

This is a topic that we could dive into at much greater depth though we are currently attending the BC Tech Summit.


#3

So I don’t need to worry about performance being an issue. That sounds amazing. Thank you for replying. Shookumscript sounds like a dream come true for me. Keep up the good work.


#4

Hey, I was wondering since blueprints now compile to native C++ in a cooked game, isn’t Skookum now the slowest option in theory?


#5

SkookumScript from its beginnings was always intended to be paired with C++. You can write awesomely fast code with C++ yet SkookumScript and C++ together are a much more powerful set of tools than C++ alone.

The key here is that they are different tools and they are each better at some jobs and worse at others. This is true for C++, SkookumScript and Blueprints in Unreal Engine 4.

C++ is likely to have greater performance crunching a lot of numbers than SkookumScript and perhaps Blueprints that are compiled to C++ might be faster than SkookumScript too. You would definitely write a rendering system in C++ and not SkookumScript and definitely not Blueprints either.

As far as performance goes, SkookumScript has three major things going for it:

  • the awesome speed of doing nothing by using concurrency
  • the best use of SkookumScript is for stage-direction
  • good old raw optimization

Great at doing nothing

You might think that after writing a bunch of SkookumScript commands for a project that you might go back and rewrite some in C++ so that key or particularly slow commands would be faster. In practice this happens very rarely - SkookumScript is fast enough and this isn’t usually a concern. However somewhat surprisingly, some C++ commands are rewritten in SkookumScript to make them faster. Huh, what!?

This is because it is so easy to write concurrency with SkookumScript that you can effortlessly spread work over time. For example, if you have an expensive test that is occurring on a bunch of game characters every frame and you really only need the test to react at “human speed” - say every third of a second - rather than every frame then you can write code like this:

loop
  [
  expensive_test
  _wait(.33)
  ]

Bam! You just spread that expensive test over time. Assuming your game is running at 60 frames per second, now rather than being called 60 times per second it will be called approximately 3 times. You’ve just created a 20X speed increase! Painstaking raw optimization can only get you so far - doing nothing is the king of speed.

There are many other ways that concurrency can be used to increase performance though this is a good simple example.

Designed for stage-direction

The ideal way to use a scripting system is to make high-level decisions and to have the game engine do most of the heavy lifting. Set a bunch of engine commands in motion, wait for results and events, perform some quick logic and set new engine commands in motion, repeat. For example, send some bad guys run over to this spot around the corner, when the player walks through this trigger area, then queue up the dramatic music and have the bad guys run to positions around the player and then attack.

The ratio of work (or processing cycles) done by the scripting system as compared to the engine should be very small. When the scripting system is waiting for the engine to complete the tasks assigned to it, the scripting system is ideally again doing nothing.

If the scripting system is doing a lot of work crunching numbers and doing a mesh deformation or calculating intersection points of a ray and a convex hull - you are probably not using it as intended.

In the case of Unreal Engine 4 - it is a huge beast of an optimized C++ engine with almost five thousand commands exposed to the scripting system. Most of the heavy lifting is going to be with those commands - not the scripting system. Thankfully, there is a massive team of men and women constantly optimizing and improving those commands. If you are so inclined you can also add your own engine or custom project commands to the mix. There are so many commands that everything you need may already be there.

In custom engines there will be a mix. Some people will write C++ code, some will write SkookumScript and many will do a mix of both.

SkookumScript is designed to work together with C++ and Blueprints with UE4.

SkookumScript is optimized

SkookumScript is compiled and not interpreted. As much work is done up-front as possible rather than during runtime. Everyone has supercomputers in their pockets in the form of their phones - there is no reason not to have the awesome might of the computers at our disposal to be put to work with our programming languages.

SkookumScript does not use a virtual machine (VM) like many scripting languages. The compiled scripts are stored in platform independent binaries and are loaded into runtime memory as data-driven optimized C++ data structures. This gives SkookumScript near native C++ speed.

The SkookumScript runtime is written in C++ and has been refined and evolved over time through repeated profiles and optimizations. A somewhat recent optimization pass increased the speed of SkookumScript by approximately 2.5X. We are big believers in profiling code to find and reduce bottlenecks - you never really know for sure unless you check.

The bindings to Unreal Engine 4 are created by crawling through the many thousands of lines of UE4 C++ code looking for the calls exposed to the Blueprint system and generating corresponding C++ bindings for SkookumScript.

Other performance considerations

Runtime speed only scratches the surface of performance considerations.

Great workflow and fast turn-around
It is one thing to run fast - it is another to allow a really quick turn-around time and to rapidly create a great product. This is the key area around which SkookumScript is designed and its greatest priority.

Being able to run arbitrarily complex commands live while the game is running on any platform is huge. The built-in game constructs such as concurrency and context from the game world editor allow you transfer your great ideas intact over to the computer without needing to twist it into computerese. This massively maximizes our most limited resource which is our puny human brains. Step-wise debugging takes concurrency into account and locks to specific game objects when the same code can be used by multiple game objects. Then the icing on the cake is that SkookumScript can modify code while a game is running without needing to stop, rebuild, play to the same progression point, hit all the same events and retest. The time saved can be a game-changer and completely change your workflow and keep you in the flow of your creative process. Some teams just starting to use SkookumScript say that they saved hours in their first week.

Also worth noting is that the SkookumScript compiler is lightning fast. The over eight thousand scripts of an entire open-world game written using SkookumScript compiles in about three seconds. This was on machines from 2010.

All of this allows for much more polish and vastly better games.

Effortless Scaling
SkookumScript excels at writing efficient concurrent code though why stop there when you can be parallel across a team too. SkookumScript has evolved on teams and is designed to be able to easily scale from small teams (even a solo hobbyist) to a huge AAA project without everyone bumping elbows. SkookumScript code files integrate well with version control. You can easily transfer script snippets over chat programs and email.

See some more advantages of using text based scripting over a visual node graph.

Efficient Memory
SkookumScript has been designed and extensively optimized to have a small memory footprint and to work efficiently with memory. All the memory used by SkookumScript comes from preallocated pools and reused data-types for predictability and speed. Automatic reference counting (ARC) is used for deterministic memory handling rather than a more heavy-handed garbage collector that runs at unpredictable times.

Just like the best way to be fast is to do nothing, the best way to have a small footprint is to not be loaded in memory - SkookumScript can use demand loading and unloading of classes. You can load and unload SkookumScript classes based on the game progression, geography, etc. If there are a bunch of missions that require a special vehicle or inventory item that you don’t have then don’t have those missions loaded in memory.

In Summary

It is possible that some specific sequences of commands in UE4 Blueprints converted to compiled C++ might be faster than SkookumScript, though we would have to profile it to be sure. SkookumScript always had the potential to be slower than well written and optimized C++ though using both is still superior to just C++. The main problem comparing SkookumScript and Blueprints is that they are different tools and you don’t ideally do the same work with them. Which is faster - a hammer or a saw? Both are faster than each other at different tasks and create higher quality work at some tasks rather than others though you create better work with both in your toolbox.

It is fantastic when other tools are improved. They make our craft better overall.

SkookumScript is a pretty amazing tool and we will continually improve it and make it a much prized part of your game development process.

EDIT: Since the original question was about Sk vs. Nativized BP performance, check out some benchmarks a year after this post.


p.s. Thanks @Gigantoad for all the references and recommendations for SkookumScript on the UE4 forums. :madsci:


Great curated posts to learn about SkookumScript
InvokedCoroutine Instantiation
Branch, Race, Sync clarification
#6

Wow, thanks for the very detailed answer! Will be a great resource to link to when the topic comes up. I’m aware of those advantages for the most part and my question was really very harmless and theoretical. You know, since the dawn of blueprints there have always been these topics of how much slower it is than C++. The figure that was thrown around was usually 10x slower. Nick Wihting explained it in a stream the other day. The issue was that each BP node went up and down the VM, so the more nodes you had, the slower it got. With the conversion to C++ during cooking, all of that is gone. Of course it’s still not as optimized as hand-written C++ code, but in most cases that’s probably negligible.

In the real world none of this might matter of course, and there are many other considerations like productivity as you mentioned (less time to write code leads to more time to optimize etc.), but a blanket statement that Skookum is faster than BP might not be true anymore at least. Some more tests would be interesting for sure. On the other hand, you’ll be opening the floodgates to more blanket statements like “Skookum is 4x slower than BP” when that won’t be true in 90% of cases. So I don’t know.

Most welcome for the recommendations and well deserved of course :slight_smile:


#7

I came to Skookum because I can’t get motivated to learn BP. It makes me angry looking at it and I give up. lol

"With the conversion to C++ during cooking, all of that is gone. "

An issue with that is they say the C++ output will not be nice to read.


#8

It’s not meant for reading, just to remove performance issues. Your blueprints are retained in the editor, you’ll still work with those. They will be converted to C++ when you cook/pack the game just in the binary that comes out of that.


#9

Wish it was readable. I’d convert the BP assets I’ve bought to C++. I’d still use Skookum to script with though, as it has constructs that makes creating quests very easy.


#10

To expand on what Noolarch said, for many types of games, SK can beat C++ in terms of “real world performance”.

I’ve been working on an SRPG for awhile using SK and his particular example comes up all the time, where I have a lot of systems that operate at “human scale” times and don’t need to be calculated or checked on every frame.

I recoded parts of the system that used to be in C++ and in practice they’re close to 100x more efficient.

Granted, there are C++ libraries that can accomplish the same thing to a degree, but they’re unwieldy at best, and you lose SK’s biggest killer feature of interactive programming. I come from a LISP and Functional Programming background and this is basically the defacto coding style in that community, which is s great addition to UE4, to be able to prototype and influence the game world in a “live” system.


#11

I feel like many people in the UE4 community seem concerned about speed prematurely. We all care about performance, but I haven’t yet worked on any projects where CPU was the limiting factor. Particularly in UE4, at least the projects I’ve worked on, GPU is always by far and away the biggest bottleneck.

I’ve never done any heavy lifting on the BP side, so perhaps before the BP compiler things were disconcertingly slow on that end. As a C++ programmer, after scripting my first boss battle in C++ I wanted to kill myself (not really :wink: but it was painful) , tons of timers everywhere, some gnarly state machines, terrible iteration time (hit compile, wait 30-50 seconds, look at lolcats, forget what you were testing).

Honestly for most game orchestration type stuff, speed is a total non-issue vs convenience. A Boeing 747 is one of the fastest means of transportation but it could be slightly inconvenient flying one to and from your mailbox.

Another thing that was linked to but not really mentioned directly was how difficult visual programming languages are to maintain. Say you need to see what was changed in a BP yesterday, a week ago etc… they are very difficult to track and diff.


#12

this is more out of curiousity than anything else but could you name one of these places where skookumscript outperforms c++ as i was actually planning to TRY to make an SRPG


#13

Mainly in the stat management and turn systems I have. My game has an ATB style system(psuedo turn based)

Things like health regen, actions orders, etc all operate at “human scale” times(like values update every second).

In vanilla UE4 you basically have to link those kinda checks to the update loop; which is wasted cycles.

To be clear, nothing about that kind of system is resource intensive and would work in vanilla UE4 without a hitch. When I say 100x more efficient we’re talking 0.001% vs 0.00001%, but it is more efficient. If the game was larger in scale like an RTS with 10,000 units this difference would matter a lot more.

Good concurrency and time management systems basically let you unlink from the update loop and, at the CPU instruction level make smarter use of NO-OPs.

Because counter intuitively you often speed things up by waiting more.


#14

@VolkerEinsfeld I know this is an old thread, and I doubt you will answer but I was wondering do you code your game mechanics in skookumscript, blueprints or c++?
By game mechanics I mean eg in call of duty the game mechanics are running and shooting and jumping
@VolkerEinsfeld


#15

@melvinbengtsen game mechanics like movement I’ve mostly done in blueprints, the actual battle system mechanics are all SK.

For stuff that’s commonly done that UE4 kinda supports out the box I just do BP still since its usually really quick.

SK works really well for my battle mechanics though, allows me to manage everything at human scale with races and coroutines for a lot of it, made translating the paper version of my system to code a lot easier.


#16

True performance benchmarks are an elusive thing. The best profiling is done when you have a more sophisticated and complete system in place.

However we’ve done lots of optimizations since this thread was first posted and we’ve had some studios mention their benchmark tests with some gratifying results:

Depending on what is being tested, It obviously won’t always be that good.
Still nice to see though. :madsci:

We’ll keep on optimizing SkookumScript. We could even nativize it in the future if the performance warrants the effort.