Dangling `=` assignment with no expressions or empty braced block `{}` on its right hand side.

Hello , as i’m learning VERSE i got into a problem.

As i was doing the Detonation Verse Template i run into this error:

Dangling = assignment with no expressions or empty braced block {} on its right hand side.

i found no errors on my side and i did tried to copy/paste or write the code multiple times.

what can i do ?

Detonation Documentation Link : Verse Detonation Template

Blockquote

bomb_state:= enum {AllUnarmed, BombAArmed, BombBArmed}

search_and_destroy := class(creative_device):

@editable

TimedObjectiveA: timed_objective_device = timed_objective_device{}

@editable

TimedObjectiveB: timed_objective_device = timed_objective_device{}

@editable

ExplosiveBarrelsA: []explosive_device = array{}

@editable

ExplosiveBarrelsB: []explosive_device = array{}

@editable

EndGameDevice: end_game_device = end_game_device{}

@editable

BombAMapIndicators: []map_indicator_device = array{}

@editable

BombBMapIndicators: []map_indicator_device = array{}

@editable

BombABeaconArm: beacon_device = beacon_device{}

@editable

BombABeaconDisarm: beacon_device = beacon_device{}

@editable

BombBBeaconArm: beacon_device = beacon_device{}

@editable

BombBBeaconDisarm: beacon_device = beacon_device{}

var BombState:bomb_state = bomb_state.AllUnarmed

# Runs when the device is started in a running game
OnBegin<override>()<suspends>:void=
    
    race:

        block:

            #wait for the Bomb A to be armed

            ArmingPlayer:= TimedObjectiveA.StartedEvent.Await()

            Print("Bomb A Armed", ?Duration:5.0)

          # Used to know which beacons to enable and barrels need to explode

          set BombState = bomb_state.BombAArmed

          # Disable the other Timed Objective device

          TimedObjectiveB.Disable(ArmingPlayer)

          # Disable map indicators for Bomb B

          for (MapIndicator : BombBMapIndicators):

            MapIndicator.Disable()


            block:

                # Wait for Bomb B to be armed

                ArmingPlayer:= TimedObjectiveB.StartedEvent.Await()

                Print("Bomb B Armed",?Duration:=5.0)

               

                # Used to know which beacons to enable and barrels need to explode

                set BombState = bomb_state.BombBArmed

               

                # Disable the other Timed Objective device

                TimedObjectiveA.Disable(ArmingPlayer)

                 # Disable map indicators for Bomb A

                for (MapIndicator : BombAMapIndicators):

                    MapIndicator.Disable()

                    # Enable the correct Beacon Devices now a bomb is armed

        UpdateBeacons()

       

        # Wait for the TimedObjective to Complete or be Stopped

        race:

            block:

                BombDetonated(TimedObjectiveA.CompletedEvent.Await())

            block:

                BombDetonated(TimedObjectiveB.CompletedEvent.Await())

           

            block:

                DisarmingPlayer:= TimedObjectiveA.StoppedEvent.Await()

                Print("Bomb Disarmed", ?Duration:=5.0)

                EndGameDevice.Activate(DisarmingPlayer)

            block:

                DisarmingPlayer:= TimedObjectiveB.StoppedEvent.Await()

                Print("Bomb Disarmed", ?Duration:=5.0)

                EndGameDevice.Activate(DisarmingPlayer)

                # Disable the unarmed Beacons and enable the Beacon over the armed bomb

    UpdateBeacons():void=

        BombABeaconArm.Disable()

        BombBBeaconArm.Disable()

       

        if:

            BombState = bomb_state.BombAArmed

        then:

            BombABeaconDisarm.Enable()

        else:

            BombBBeaconDisarm.Enable()

            BombDetonated(Agent:agent):void=

            Print("Bomb Detonated", ?Duration:=5.0)

        # Determine which set barrels should explode

        if:

            BombState = bomb_state.BombAArmed

        then:

            ExplodeBarrels(ExplosiveBarrelsA, Agent)

        else:

            ExplodeBarrels(ExplosiveBarrelsB, Agent)

        EndGameDevice.Activate(Agent)

        ExplodeBarrels(Barrels:[]explosive_device, Agent:agent):void=

            for (Barrel : Barrels):

                Barrel.Explode(Agent)

Quite difficult to check everything cause of the formatting but BombDetonated(Agent:agent):void= doesn’t look right in your UpdateBeacons method.

Try removing the :void= after calling the BombDetonated method so it looks like this BombDetonated(Agent:agent).

Hello, Thanks for your quick answer but unfortunately it didn’t work , templates should have a file that we can download so it would be easier for us to learn… anyway i’ll try again soon

if you got any other idea let me know !

Ah ok, yeah you’re right, at first glance it looked like you were trying to call BombDetonated with a definition but it was actually the definition ha, the indention threw me off!

I haven’t actually used this script/tutorial but I’ve just gone through it and taken the code snippets they’ve provided and put it into a single file. Done the same with yours and formatted/indented to the same as the original. Popped it in a diff checker and noticed that this:

Print("Bomb A Armed",?Duration:5.0)

Should be:

Print("Bomb A Armed",?Duration:=5.0)

It’s missing the = which I believe corresponds to the error you’re getting as it wouldn’t compile, but I would have thought you should have gotten an error in VSCode already?

But try that and let me know.

And just for reference, here is the full script taken from the tutorial (it doesn’t include the imports at the top using { ... } etc though so make sure you add them back in)

# enum to determine the state of the bombs
bomb_state<public>:= enum {AllUnarmed, BombAArmed, BombBArmed}

search_and_destroy := class(creative_device):
    Logger:log = log{Channel:=log_search_and_destroy}

    @editable
    TimedObjectiveA: timed_objective_device = timed_objective_device{}

    @editable
    TimedObjectiveB: timed_objective_device = timed_objective_device{}

    @editable
    ExplosiveBarrelsA: []explosive_device = array{}

    @editable
    ExplosiveBarrelsB: []explosive_device = array{}

    @editable
    EndGameDevice: end_game_device = end_game_device{}

    @editable
    BombAMapIndicators: []map_indicator_device = array{}

    @editable
    BombBMapIndicators: []map_indicator_device = array{}

    @editable
    BombABeaconArm: beacon_device = beacon_device{}

    @editable
    BombABeaconDisarm: beacon_device = beacon_device{}

    @editable
    BombBBeaconArm: beacon_device = beacon_device{}

    @editable
    BombBBeaconDisarm: beacon_device = beacon_device{}

    var BombState:bomb_state = bomb_state.AllUnarmed

    # Runs when the device is started in a running game
    OnBegin<override>()<suspends>:void=
        # The race expression is used to run a block of two or more async expressions concurrently (simultaneously). When the fastest expression completes, it "wins the race".
        # https://www.fortnite.com/en-US/creative/docs/uefn/race-in-verse
        race:
            block:
                # Wait for Bomb A to be armed
                ArmingPlayer:= TimedObjectiveA.StartedEvent.Await()
                Print("Bomb A Armed",?Duration:=5.0)

                # Used to know which beacons to enable and barrels need to explode
                set BombState = bomb_state.BombAArmed

                # Disable the other Timed Objective device
                TimedObjectiveB.Disable(ArmingPlayer)

                # Disable map indicators for Bomb B
                for (MapIndicator : BombBMapIndicators):
                    MapIndicator.Disable()

            block:
                # Wait for Bomb B to be armed
                ArmingPlayer:= TimedObjectiveB.StartedEvent.Await()
                Print("Bomb B Armed",?Duration:=5.0)

                # Used to know which beacons to enable and barrels need to explode
                set BombState = bomb_state.BombBArmed

                # Disable the other Timed Objective device
                TimedObjectiveA.Disable(ArmingPlayer)

                # Disable map indicators for Bomb A
                for (MapIndicator : BombAMapIndicators):
                    MapIndicator.Disable()

        # Enable the correct Beacon Devices now a bomb is armed
        UpdateBeacons()

        # Wait for the TimedObjective to Complete or be Stopped
        race:
            block:
                BombDetonated(TimedObjectiveA.CompletedEvent.Await())

            block:
                BombDetonated(TimedObjectiveB.CompletedEvent.Await())

            block:
                DisarmingPlayer:= TimedObjectiveA.StoppedEvent.Await()
                Print("Bomb Disarmed", ?Duration:=5.0)
                EndGameDevice.Activate(DisarmingPlayer)

            block:
                DisarmingPlayer:= TimedObjectiveB.StoppedEvent.Await()
                Print("Bomb Disarmed", ?Duration:=5.0)
                EndGameDevice.Activate(DisarmingPlayer)

    # Disable the unarmed Beacons and enable the Beacon over the armed bomb
    UpdateBeacons():void=
        BombABeaconArm.Disable()
        BombBBeaconArm.Disable()
        
        if:
            BombState = bomb_state.BombAArmed
        then:
            BombABeaconDisarm.Enable()
        else:
            BombBBeaconDisarm.Enable()

    BombDetonated(Agent:agent):void=
        Print("Bomb Detonated", ?Duration:=5.0)

        # Determine which set barrels should explode
        if:
            BombState = bomb_state.BombAArmed
        then:
            ExplodeBarrels(ExplosiveBarrelsA, Agent)
        else:
            ExplodeBarrels(ExplosiveBarrelsB, Agent)

        EndGameDevice.Activate(Agent)

    ExplodeBarrels(Barrels:[]explosive_device, Agent:agent):void=
        for (Barrel : Barrels):
            Barrel.Explode(Agent)

Just an FYI, I haven’t tested this, I just put the snippets together…

Hello thanks for taking your time to help me. Unfortunately your code give me more warnings errors than i had before for no really apparent reason !

I think i will wait for UEFN to be updated and see how it goes from there ! for the moment it is a horrible pain to learn and write Verse code !

Have a nice day !

Apologies it doesn’t work, I’ve yet to have time to try it personally to verify any of it. When I do, I’ll write up another post with the result. In the meantime have you checked that you’ve assigned all the @editable props/devices correctly inside UEFN to that Verse script? Just so you know everything on that end is aligned correctly.

Out of curiosity do you know or have prior experience with any programming languages? I’ve found a few things with Verse interesting and unusual compared to what I’m used to with other programming languages. I’ve not found it too difficult to navigate the docs and understand whats available etc though, but I do work with code every day, so that may help.

I would say carry on and keep trying to get it work, it may be frustrating but it starts making more sense the more you work with it. Same with any language, more so with this one as its all new.

It doesn’t help that the formatting on that tutorial is broken up and in sections and indentation doesn’t line up everywhere, especially when working with a language that operates based on indentation/formatting.

I’ll hopefully have time this weekend to go through this tutorial for you and post my results!

Hello and again thanks for your answers , yes i did assigned all @editable devices inside UEFN correctly as the tutorial does.

I do have experience with others programming language as C++,HTML,CSS,C#…

I’ve been reading almost the whole documentation but it seem like something is missing , maybe i’m not used to the syntax or logics of Verse yet.

I’ll wait for your result ! Thanks for your time and have a nice day.

Wow… so I’ve just started following the tutorial properly and its actually not that great is it. It’s outdated, missing references/devices, inconsistant formatting in the code snippets. Not great for new people trying to learn, which is pretty much everyone…

First of all, the tutorial creates a logger but doesn’t declare the indentifier for it.

# Unknown identifier `log_search_and_destroy`.
Logger: log = log { Channel := log_search_and_destroy }

So it needs this before the creative device class declaration.

log_search_and_destroy := class(log_channel){}

The next thing is on the OnBegin method, the race conditions will error for 3 reasons.

The first being that TimedObjectiveA and TimedObjectiveB are both trying to call StartedEvent, which doesn’t exist on the timed_objective_device, it’s BeganEvent.

ArmingPlayer := TimedObjectiveA.StartedEvent.Await() 
# Unknown member `StartedEvent` in `timed_objective_device`.

The same goes for the StoppedEvent, that should be EndedEvent instead.

DisarmingPlayer := TimedObjectiveA.StoppedEvent.Await()
# Unknown member `StoppedEvent` in `timed_objective_device`.

Which that then also caused the race condition to be invalid as no Async method was expressed in the condition.

Expected async expression(s) (such as a coroutine or concurrency primitive) and only found immediate expression(s) (such as an immediate function call).

The next thing is the tutorial doesn’t even mention to add beacon_devices to the world for the BombABeaconArm, BombABeaconDisarm, BombBBeaconArm and BombBBeaconDisarm.

They are included in the Verse Detonation Template that comes with UEFN, but the tutorial only tells you to reference them within the Verse device, it doesn’t have a section on setting them up. It doesn’t even mention them in the list of devices you’re going to use at the start of the tutorial.

This tutorial uses the following devices:
    8 x Explosive
    2 x Timed Objectives
    4 x Map Indicators
    1 x End Game
    ~ x Player Spawn Pad
    1 x Verse

So it’s not very helpful if you’re not using the template, which why would you if the tutorial tells you not too.

So you have to add those yourself, and it doesn’t even tell you how to configure them properly so you’ll need to copy them over from the Verse Detonation Template and paste them into your project and place them above their respective bomb sites.

But after following the tutorial, and making all those changes above, I’ve got a working game with the following script:


using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }

# Logs
log_search_and_destroy := class (log_channel) {}

# Types
bomb_state<public> := enum { AllUnarmed, BombAArmed, BombBArmed }

# Creative device
search_and_destroy  := class (creative_device) {
    Logger: log = log { Channel := log_search_and_destroy }

    @editable
    BombAMapIndicators: []map_indicator_device = array {}

    @editable
    BombABeaconArm: beacon_device = beacon_device {}

    @editable
    BombABeaconDisarm: beacon_device = beacon_device {}

    @editable
    BombBMapIndicators: []map_indicator_device = array {}

    @editable
    BombBBeaconArm: beacon_device = beacon_device {}

    @editable
    BombBBeaconDisarm: beacon_device = beacon_device {}

    @editable
    ExplosiveBarrelsA: []explosive_device = array {}

    @editable
    ExplosiveBarrelsB: []explosive_device = array {}

    @editable
    TimedObjectiveA: timed_objective_device = timed_objective_device {}

    @editable
    TimedObjectiveB: timed_objective_device = timed_objective_device {}

    @editable
    EndGameDevice: end_game_device = end_game_device {}

    # Set the initial bomb state to all bombs unarmed
    var BombState: bomb_state = bomb_state.AllUnarmed

    # Runs when the device is started in a running game
    # @return {void}
    OnBegin<override>()<suspends>: void = {
        # Start a race to check which bomb is armed first
        race {
            # Wait for bomb a to be armed
            block {
                # Set the player who armed bomb a
                ArmingPlayer := TimedObjectiveA.BeganEvent.Await() 
                Print("Bomb A Armed", ?Duration := 5.0)
                
                # Set the bomb state to bomb a armed
                set BombState = bomb_state.BombAArmed
                
                # Disable the other timed objective
                TimedObjectiveB.Disable(ArmingPlayer)
                
                # Iterate through all of the map indicators for bomb b
                for (MapIndicator: BombBMapIndicators) {
                    # Disable map indicator for bomb b
                    MapIndicator.Disable()
                }
            }
            
            # Wait for bomb b to be armed
            block {
                # Set the player who armed bomb b
                ArmingPlayer := TimedObjectiveB.BeganEvent.Await()
                Print("Bomb B Armed", ?Duration := 5.0)
                
                # Set the bomb state to bomb b armed
                set BombState = bomb_state.BombBArmed
                
                # Disable the other timed objective
                TimedObjectiveA.Disable(ArmingPlayer)
                
                # Iterate through all of the map indicators for bomb a
                for (MapIndicator: BombAMapIndicators) {
                    # Disable map indicator for bomb a
                    MapIndicator.Disable()
                }
            }
        }

        # Set the correct beacons to be enabled
        UpdateBeacons()

        # Start a race to check if a timed objective is completed or stopped
        race {
            # Wait for bomb a to be detonated
            block {
                # Detonate bomb a
                BombDetonated(TimedObjectiveA.CompletedEvent.Await())
            }

            # Wait for bomb b to be detonated
            block {
                # Detonate bomb b
                BombDetonated(TimedObjectiveB.CompletedEvent.Await())
            }

            # Wait for bomb a to be disarmed
            block {
                # Set the player who disarmed bomb a
                DisarmingPlayer := TimedObjectiveA.EndedEvent.Await()
                Print("Bomb Disarmed", ?Duration := 5.0)

                # Activate the end game
                EndGameDevice.Activate(DisarmingPlayer)
            }

            # Wait for bomb b to be disarmed
            block {
                # Set the player who disarmed bomb b
                DisarmingPlayer := TimedObjectiveB.EndedEvent.Await()
                Print("Bomb Disarmed", ?Duration := 5.0)

                # Activate the end game
                EndGameDevice.Activate(DisarmingPlayer)
            }
        }
    }

    # Called when a bomb is detonated.
    # @param  {agent}  Agent  The agent that detonated the bomb.
    # @return {void}
    BombDetonated(Agent: agent): void = {
        Print("Bomb Detonated", ?Duration := 5.0)

        # Check if bomb a was armed
        if (BombState = bomb_state.BombAArmed) {
            # Explode barrels for bomb a
            ExplodeBarrels(ExplosiveBarrelsA, Agent)
        } else {
            # Explode barrels for bomb b
            ExplodeBarrels(ExplosiveBarrelsB, Agent)
        }

        # Activate the end game
        EndGameDevice.Activate(Agent)
    }

    # Explode all the barrels.
    # @param  {[]explosive_device}  Barrels  The barrels to explode.
    # @param  {agent}               Agent    The agent that detonated the bomb.
    # @return {void}
    ExplodeBarrels(Barrels: []explosive_device, Agent: agent): void = {
        # Iterate through all of the barrels
        for (Barrel: Barrels) {
            # Explode the barrel
            Barrel.Explode(Agent)
        }
    }

    # Set the correct beacons to be enabled.
    # @return {void}
    UpdateBeacons(): void = {
        # Disable all arm beacons
        BombABeaconArm.Disable()
        BombBBeaconArm.Disable()

        # Check if bomb a was armed
        if (BombState = bomb_state.BombAArmed) {
            # Enable the bomb a disarm beacon
            BombABeaconDisarm.Enable()
        } else {
            # Enable the bomb b disarm beacon
            BombBBeaconDisarm.Enable()
        }
    }
}
2 Likes

Hello

First thanks for your precise and informative answer , i appreciate the fact that you took your own time to help people learning verse.

I saw in the devices documentation that StartedEvent wasn’t existing but i didn’t had the intelligence to try things on my own this time !

That was a hell of a ride to learn this Detonation Template but your help has helped me a lot and the code is now working and you teached me a lot of things.

Again , thanks you and have a nice day.

1 Like

No problem at all, I’m glad you were able to get it working and learn some new things!

2 Likes

hey there first of all thankyou for the code as i am new to verse and still trying to learn it better . i am having an issue where i am not able to link the bomb beacon arm as it only gives me one option which is my map :confused:

1 Like