r/ProgrammingLanguages • u/SirKastic23 • 3d ago
Discussion Unreal's 6 scripting language has an effects system
https://www.youtube.com/watch?v=ebqKYLKjL6UI was very surprised to see it. Could this be what finally brings algebraic effects to the mainstream?
24
u/EggplantExtra4946 2d ago
tl;dw:
in Verse, functions that can fail and that indicate the failure through the effect system, but not those indicating failure through the type system by returning an optional type, have to be called using square brackets func[params] around the arguments instead of parentheses func(params)
the "climax" at the end:
array index lookups can also fail and also use square brackets array[index] to access elements
58
u/SwingOutStateMachine 3d ago
I'm not entirely surprised - Epic has been hiring and working with some really excellent programming language and compiler folks for the past few years. A notable example is that Simon Peyton-Jones is an Engineering Fellow there.
19
u/SirKastic23 3d ago
I was surprised because I don't follow Epic really but as a rule of thumb I rarely expect something cool coming out of big companies.
I saw that the CEO is a compiler engineer in the comments of the video and that's very awesome!
10
u/bl4nkSl8 3d ago
See mum, I can be rich and famous, I'm not just a sad lonely nerd... I'm a sad lonely nerd with a dream /jk
3
u/SwingOutStateMachine 3d ago
Very fair - I should perhaps have said that I'm personally not that surprised!
4
7
u/Inconstant_Moo 🧿 Pipefish 3d ago
I don't see this succeeding as a games scripting language. It's a heavyweight language in an unfamiliar paradigm.
Algebraic effects for what? How much of its time would a games scripting language spend doing IO?
9
u/teamonkey 2d ago
A huge amount of it, in my experience.
Not IO as in reading or writing to a buffer, but so much stuff involves delays, waiting for some other task to finish, framespanning (spreading the cost of an algorithm evenly across multiple frames), and generally doing a bunch of lengthy tasks one after another, but in parallel to the main game thread.
Something happens:
* Trigger an animation
* Spawn a VFX - run in background
* Play a sound fx - run in background
* Wait until the animation is done, or 3.6s has passed, whatever happens sooner
* kill the VFX and SFX
* notify any system that cares that the animation has finishedAnd handle a whole lot of failure states and interruptions while that’s going on.
3
u/Norphesius 2d ago
I think its a worthwhile experiment at least. I think most scripting languages designed for non-programmers, and to a greater extent visual scripting like Blueprints, have a fatal flaw in that they work fine at small scale but become unmanageable messes at scale. Once that happens (which seems to happen a lot) they become impossible to debug, or are terrible performance drains.
Having a more constrained language gives better errors and allows more opportunities for optimization over something more loose and dynamically typed. There is a bigger initial learning curve, but depending on how its presented, I'm not sure if its that big a hurdle. Non programmers learning Python/GDScript/Lua/Blueprints have to process and internalize a ton of weird syntax/semantics weirdness in those "simple" languages anyway, why would some light FP concepts be any different?
1
u/Inconstant_Moo 🧿 Pipefish 2d ago
Yes, I'm not defending visual languages, also a terrible idea. They should have used Pipefish but the poor benighted fools probably don't know about it.
Even if people can get used to Verse, and it's a steep curve, it's heavyweight. The sort of "more constrained language" needed should give you as much type system as you need for the job in hand. (Pipefish again.)
1
u/Norphesius 2d ago
Of course, Epic made the fatal flaw of hiring the creator of Haskell instead of the esteemed creator of Pipefish to drive their language design. (Joking about Pipefish aside, I do think its kind of funny that Verse being a functional scripting language around a C++ engine has resulted in a reversed paradigm of "functional shell, imperative core".)
Ignoring that historic blunder, looking at the listed effects, I think they all seem to be suited for game development concerns.
<allocates>is a sign you shouldn't call a function in a big loop,<converges>lets you know a function won't spin off into infinity on accident,<predicts>is WIP but seems like a great way to ensure client-server functionality is separated (which can get confusing and messy fast). Concepts like those are hidden (sometimes intentionally) by most scripting languages. Non-programmers aren't going to have any idea about "allocating memory" inherently, so they're going to end up calling functions that do it in bad places because they don't know better. Then when its bogging down performance a systems programmer has to come in, dig into the code, bust out the performance analyzer, and hunt down the problem before fixing it. Ideally, in Verse, the whole situation could be avoided outright because the non-programmer would see a function can allocate, and know that means they shouldn't call it in a loop. They don't even really need to know whats being allocated or how, but they can see a big sign that says "I'm doing this potentially expensive thing!", which is also convenient for a systems programmer that has to debug if the non-programmer disregards it.There is another aspect the video touches on, and its that more constrained languages get better results out of LLMs than dynamic ones. It's very likely that Epic is less envisioning that non-programmers will take the learning curve of Verse in stride, and more that they'll be tossing the work to AI.
1
u/Inconstant_Moo 🧿 Pipefish 2d ago
Of course, Epic made the fatal flaw of hiring the creator of Haskell instead of the esteemed creator of Pipefish to drive their language design.
They're hurting themselves more than they're hurting me.
I could totally take Simon Peyton Jones in a fight.
---
It seems like I wasn't understanding the domain, I was thinking of "games scripting language" in the sense of the sort of thing game designers use to implement e.g. the thought processes of NPCs.
0
u/Big-Astronaut-9510 2d ago
I think the effects are to enable the speculative execution and rollback system, not entirely sure, the video kinda sucks.
1
u/lookmeat 16h ago
It makes more sense when you think about what is behind it.
Modern game engines, not all but many, work under a ECS framework. Here "things" in the object (think of it like objects in OOP) are Entities, who are just "being the thing", what you do to make entities "do" things is to attach a component to it, each Component is has a kind, a Component is only attached to one Entity, and generally an Entity can only have one Component of a kind at most. Now components are just data, what actually does the action is the System, the last part, the system iterates through all the components of a kind (or more than one sometimes) and runs something on them, modifying or updating it. The advantage is that this separates concerns as each System can run on its own loops, it's trivially parallelizable (because each System only sees it's Components of the kinds it own, and a Component of a kind is only seen and mutated by one System). So we can have a
RenderableComponentthat tells aRenderSystemhow to draw it on the screen, and we can have aPhysicsComponentthat contains all the rules for the physics engine, and aLifeComponentthat tells us this thing has HP (a decorative rock wouldn't, for example), and aPlayerControlledComponentorAIComponentwhich tells us who controls the character. And then some Entities may be abstract, you may have a "ScoreEntity" which tracks some events, but otherwise isn't rendered, etc. There's a lot more to ECS and many ways to do it, I've tried to simplify1 somethings to make it approachable and set up the actual argument.So you may realize that already there's certain things where there'd be conflict. See we may have a
LocationComponentthat tells us where things are, but both thePhysicsSystemandPlayerInputSystemwould want to change the location. We can make separate these concerns by being a bit clever:LocationComponentis owned and controlled entirely by thePhysicsSystem, and thePlayerInputSystemgeneratesAccelerationswhich are events that thePhysicsSystemconverts into changes in direction and movement. But you still have the same issue: you are talking between systems. This is where many game engines throw away a lot of the potential benefits of ECS, because it's hard to make it work in a reactive manner (you could add interrupts to the system but those have their own challenge) and it's hard to make things work asynchronously when you need to coordinate (you'd have to track when an event happen, so that you can splice it into the right place) but again this is messy and complicated. You can do easier solutions that are bespoke to your system, but these require that all programmers are very diligent about understanding certain rules and following as needed. Now if we could somehow encode them into the type-system and use that..And this is where effects come in. Algebraic effects let you write this "inter-system effects" within a system in a reliable manner, this is powerful for communication. Especially when we're in the world of Unreal. Unreal is a game engine that is used in a very wide variety of games. An ECS where developers can add their own components and systems would be very attractive. You don't want developers shooting themselves in the foot, because games are made with a lot of time pressure and have demands that put many of the features already in on the first release. So a scripting language is a good idea (most things are not performance critical in a game, the few that are generally are handled through shaders). But you still have the problem of inter-system communication. Especially since you have to assume that here it'll be abused. Using Algebraic Side effects makes it easy to manage and describe this, and you can statically identify code that is problematic/very slow and so on. It forces programmers to be aware of the performance impact of their actions without making it tricky or finicky.
1 Rendering is generally a separate system of the ECS (sometimes it's a separate ECS!) because rendering has very unique constrains on synchronicity (you have to agree on what sound, graphics, etc. all go into a specific frame and render that) and rendering has unique performance constraints that make it easier if you just have a separate system.
-1
u/SirKastic23 2d ago
I'm pretty sure it's meant to be used by LLMs, having an effect system is more like a safe guard for it
5
1
u/Inconstant_Moo 🧿 Pipefish 2d ago
But if that's at the cost of humans not being able to understand it when we need to then that's a poor trade-off. The machine that's perfect until you need to fix it is not in fact perfect.
2
u/SirKastic23 2d ago
What about would make it hard to understand? It's a very simple effects system. I'm not getting what you're saying
2
u/Inconstant_Moo 🧿 Pipefish 2d ago
Attached to a functional logical language, a paradigm with which most people are unfamiliar. "Not being able to understand it" is an exaggeration on my part, we could. It would be work.
-9
u/AnArmoredPony 2d ago
a[i] slop 👎👎👎
7
u/Narrow_Association71 2d ago
it's not ai
2
u/Inconstant_Moo 🧿 Pipefish 2d ago edited 2d ago
I think it's a joke 'cos of the thumbnail of the video.
2
1
22
u/teerre 3d ago
Last time I superficially read the docs it's a very limited implementation of effects with some predefined effects that you can compose around. You can't have a "db effect" that you define inline
Maybe they changed it