VerseIsland
Feed Learn Leaderboard Guides Reference Explore Search Docs Verse Library
Sign in
Feed Learn 📖 Codex Leaderboard Guides Reference Explore Search Docs Verse Library
Verse Library › Player
Browse Verse Library

Library

Devices 634
  • Devices171
  • Triggers & Logic118
  • UI & HUD40
  • Audio39
  • Items & Inventory29
  • Events27
  • Scoring & Objectives25
  • Spawning19
  • Classes & Interfaces18
  • Game Modes17
  • Props & Meshes14
  • Variables & Mutability12
  • Player Management11
  • Modules & Structure10
  • Round Flow8
  • Animation6
  • Concurrency6
  • Functions6
  • Getting Started6
  • Teams & Classes6
  • NPCs & AI5
  • Tutorials5
  • VFX & Particles5
  • Arrays & Maps4
  • Cameras4
  • Debugging4
  • Control Flow3
  • Cinematics2
  • Other2
  • Persistence2
  • Scene Graph2
  • Structs & Enums2
  • Building1
  • Physics1
  • Publishing & Islands1
  • Syntax & Types1
  • Vehicles1
  • Weapons1
Verse Language 257
  • Control Flow35
  • Functions26
  • Arrays & Maps25
  • Classes & Interfaces22
  • Variables & Mutability22
  • Concurrency21
  • Syntax & Types18
  • Modules & Structure12
  • Debugging8
  • Devices8
  • Events7
  • Player Management6
  • Structs & Enums6
  • Triggers & Logic6
  • Game Modes5
  • Failure & Options4
  • Scene Graph4
  • UI & HUD4
  • Getting Started3
  • Round Flow3
  • Spawning3
  • VFX & Particles3
  • Reference2
  • Animation1
  • Best Practices1
  • Other1
  • Props & Meshes1
Materials/VFX 154
  • Triggers & Logic27
  • UI & HUD17
  • Devices16
  • VFX & Particles14
  • Props & Meshes11
  • Scoring & Objectives9
  • Game Modes7
  • Items & Inventory7
  • Functions6
  • Arrays & Maps5
  • Animation3
  • Cinematics3
  • Classes & Interfaces3
  • Control Flow3
  • Events3
  • Modules & Structure3
  • Round Flow3
  • Spawning3
  • Getting Started2
  • Scene Graph2
  • Variables & Mutability2
  • Concurrency1
  • Persistence1
  • Player Management1
  • Structs & Enums1
  • Syntax & Types1
General 153
  • Devices22
  • Events20
  • Triggers & Logic20
  • Classes & Interfaces10
  • Variables & Mutability8
  • Round Flow6
  • Scoring & Objectives6
  • UI & HUD6
  • Functions5
  • Player Management5
  • Game Modes4
  • Getting Started4
  • Props & Meshes4
  • Control Flow3
  • Syntax & Types3
  • VFX & Particles3
  • Arrays & Maps2
  • Best Practices2
  • NPCs & AI2
  • Other2
  • Physics2
  • Scene Graph2
  • Spawning2
  • Structs & Enums2
  • Tutorials2
  • Building1
  • Cameras1
  • Cinematics1
  • Failure & Options1
  • Items & Inventory1
  • Teams & Classes1
Player 133
  • Player Management22
  • Teams & Classes19
  • Classes & Interfaces12
  • Devices11
  • Events9
  • Persistence7
  • Triggers & Logic7
  • Arrays & Maps6
  • Functions4
  • Game Modes4
  • Items & Inventory4
  • Round Flow4
  • Debugging3
  • Getting Started3
  • Modules & Structure3
  • Concurrency2
  • Control Flow2
  • Scoring & Objectives2
  • Spawning2
  • Structs & Enums2
  • Physics1
  • Props & Meshes1
  • UI & HUD1
  • Variables & Mutability1
  • Weapons1
Building & Props 131
  • Variables & Mutability15
  • Props & Meshes14
  • Triggers & Logic12
  • Classes & Interfaces10
  • Devices10
  • UI & HUD10
  • Events7
  • Teams & Classes7
  • Animation5
  • Building5
  • Functions5
  • VFX & Particles5
  • Structs & Enums4
  • Control Flow3
  • Game Modes3
  • Items & Inventory3
  • Round Flow3
  • Scene Graph3
  • Arrays & Maps2
  • Concurrency2
  • Reference2
  • Modules & Structure1
NPCs & AI 76
  • NPCs & AI35
  • Spawning7
  • Animation5
  • Variables & Mutability5
  • Classes & Interfaces3
  • Debugging3
  • UI & HUD3
  • Audio2
  • Concurrency2
  • Game Modes2
  • Props & Meshes2
  • Triggers & Logic2
  • Devices1
  • Functions1
  • Getting Started1
  • Reference1
  • VFX & Particles1
Spawning 73
  • Spawning31
  • Events7
  • Concurrency6
  • Player Management6
  • Vehicles5
  • Props & Meshes4
  • Devices3
  • Scene Graph3
  • Items & Inventory2
  • Teams & Classes2
  • Control Flow1
  • Publishing & Islands1
  • Reference1
  • Scoring & Objectives1
Cinematics 71
  • Cameras19
  • Cinematics15
  • Devices11
  • Audio5
  • Animation4
  • Triggers & Logic4
  • Functions2
  • Game Modes2
  • UI & HUD2
  • Classes & Interfaces1
  • Concurrency1
  • Control Flow1
  • Items & Inventory1
  • Modules & Structure1
  • Scene Graph1
  • Templates1
UI 57
  • UI & HUD35
  • Devices5
  • Scoring & Objectives4
  • Classes & Interfaces3
  • Round Flow2
  • Scene Graph2
  • Arrays & Maps1
  • Props & Meshes1
  • Structs & Enums1
  • Templates1
  • Triggers & Logic1
  • Variables & Mutability1
Scene Graph 40
  • Scene Graph9
  • Items & Inventory8
  • Classes & Interfaces3
  • Events3
  • Props & Meshes3
  • Functions2
  • Arrays & Maps1
  • Building1
  • Control Flow1
  • Debugging1
  • Modules & Structure1
  • Player Management1
  • Reference1
  • Structs & Enums1
  • Syntax & Types1
  • Triggers & Logic1
  • UI & HUD1
  • VFX & Particles1
Vehicles 38
  • Spawning11
  • Devices7
  • Vehicles7
  • Props & Meshes4
  • Functions2
  • Game Modes2
  • Failure & Options1
  • Items & Inventory1
  • Reference1
  • Teams & Classes1
  • Tutorials1
Tutorials 37
  • Game Modes6
  • Triggers & Logic5
  • Classes & Interfaces4
  • Events4
  • Props & Meshes3
  • Building2
  • Devices2
  • Items & Inventory2
  • Scoring & Objectives2
  • Animation1
  • Arrays & Maps1
  • Cameras1
  • Concurrency1
  • Physics1
  • Player Management1
  • Structs & Enums1
Weapons 30
  • Game Modes6
  • Weapons6
  • Devices5
  • Items & Inventory3
  • Scoring & Objectives3
  • Spawning2
  • Teams & Classes2
  • Best Practices1
  • Functions1
  • Triggers & Logic1
Items 28
  • Items & Inventory23
  • Devices2
  • Triggers & Logic2
  • Spawning1
Assets 20
  • Modules & Structure6
  • Arrays & Maps3
  • Functions3
  • Scene Graph2
  • Best Practices1
  • Devices1
  • Events1
  • Failure & Options1
  • Physics1
  • Variables & Mutability1
Animation 19
  • Animation10
  • Variables & Mutability4
  • Devices1
  • Player Management1
  • Props & Meshes1
  • Scene Graph1
  • Syntax & Types1
Release Notes 17
  • Classes & Interfaces5
  • Modules & Structure3
  • Concurrency2
  • Control Flow2
  • Variables & Mutability2
  • Debugging1
  • Devices1
  • Items & Inventory1
Input & Controls 16
  • Functions4
  • UI & HUD3
  • Control Flow2
  • Animation1
  • Arrays & Maps1
  • Cinematics1
  • Debugging1
  • Devices1
  • Events1
  • Items & Inventory1
Publishing 8
  • Control Flow5
  • Arrays & Maps1
  • Devices1
  • Syntax & Types1
Audio 7
  • Audio5
  • UI & HUD2
Landscape 7
  • Other4
  • VFX & Particles2
  • Scene Graph1
Persistence 6
  • Structs & Enums2
  • Items & Inventory1
  • Persistence1
  • Publishing & Islands1
  • Variables & Mutability1
Physics 5
  • Functions2
  • Classes & Interfaces1
  • Devices1
  • Syntax & Types1
Creator Economy 3
  • Publishing & Islands2
  • Modules & Structure1
Discovery 3
  • Devices1
  • NPCs & AI1
  • Structs & Enums1
Editor & Project 3
  • Other1
  • Props & Meshes1
  • Tutorials1

Graph Data Structures

Module — 3 files
These files compile together (same module folder).
file_1.verse
# Module library for mathematical graphs in Verse
Graphs<public> := module:

    using { /Verse.org/Random }

    # Integer weighted graph
    IntegerWeightedGraph<public> := class<concrete>:

        Vertices:?[]int = false
        Edges:?[]tuple(int,int,int) = false
        AdjacencyList:?[int][]tuple(int,int) = false

        GetEdges<public>()<decides><transacts>:[]tuple(int,int,int) =
            Edges?

        GetVertices<public>()<decides><transacts>:[]int =
            Vertices?

        GetAdjacencyList<public>()<decides><transacts>:[int][]tuple(int,int) =
            AdjacencyList?

        DebugString<public>()<transacts>:string =
            var ReturnString: string = ""
            if (List:=AdjacencyList?):
                for (Vertex->VertexEdges:List):
                    for(Edge:VertexEdges):
                        set ReturnString += "\t{Vertex} - ({Edge(1)}) -> {Edge(0)}\n"
            ReturnString

    # Float weighted graph
    FloatWeightedGraph<public> := class<concrete>:

        Vertices:?[]int = false
        Edges:?[]tuple(int,int,float) = false
        AdjacencyList:?[int][]tuple(int,float) = false

        GetEdges<public>()<decides><transacts>: []tuple(int,int,float) =
            Edges?

        GetVertices<public>()<decides><transacts>: []int =
            Vertices?

        GetAdjacencyList<public>()<decides><transacts>: [int][]tuple(int,float) =
            AdjacencyList?

        DebugString<public>()<transacts>:string =
            var ReturnString: string = ""
            if (List:=AdjacencyList?):
                for (Vertex->VertexEdges:List):
                    for(Edge:VertexEdges):
                        set ReturnString += "\t{Vertex} - ({Edge(1)}) -> {Edge(0)}\n"
            ReturnString

    # Obtain list of vertices from an adjacency list
    GetVerticesFromAdjacencyList<internal>(AdjacencyListIn:[t][]tuple(t,s) where t:subtype(int), s:subtype(comparable))<decides><transacts>:[]t =
        var Vertices:[]t = array{}
        for (Vertex->VertexEdges:AdjacencyListIn):
            set Vertices += array{Vertex}
        Vertices

    # Obtain list of edges from adjacency list
    GetEdgesFromAdjacencyList<internal>(AdjacencyListIn:[t][]tuple(t,s) where t:subtype(int), s:subtype(comparable))<decides><transacts>: []tuple(t,t,s) =
        var Edges: []tuple(t,t,s) = array{}
        for (Vertex->VertexEdges:AdjacencyListIn):
            for (Edge:VertexEdges):
                set Edges += array{(Vertex,Edge(0),Edge(1))}
        Edges

    # Create an adjacency list from vertices and edges
    BuildAdjacencyList<internal>(VerticesIn:[]t, EdgesIn:[]tuple(t,t,s) where t:subtype(int), s:subtype(comparable))<decides><transacts>: [t][]tuple(t,s) =
        var AdjacencyListTemp: [t][]tuple(t,s) = map{}
        for (Vertex:VerticesIn):
            set AdjacencyListTemp[Vertex] = array{}
        for (Triple:EdgesIn):
            Source := Triple(0)
            Destination := Triple(1)
            Weight := Triple(2)
            set AdjacencyListTemp[Source] += array{(Destination, Weight)}
        AdjacencyListTemp

    # Create an integer weighted graph
    BuildIntegerWeightedGraph<public><constructor>(AdjacencyList:[int][]tuple(int,int)):=IntegerWeightedGraph:
        Vertices := option{GetVerticesFromAdjacencyList[AdjacencyList]}
        Edges := option{GetEdgesFromAdjacencyList[AdjacencyList]}
        AdjacencyList := option{AdjacencyList}

    # Create a float weidghted graph
    BuildFloatWeightedGraph<public><constructor>(AdjacencyList:[int][]tuple(int,float)):=FloatWeightedGraph:
        Vertices := option{GetVerticesFromAdjacencyList[AdjacencyList]}
        Edges := option{GetEdgesFromAdjacencyList[AdjacencyList]}
        AdjacencyList := option{AdjacencyList}

    # Internal Constructor for integer weighted graph
    BuildIntegerWeightedGraphVE<constructor>(Vertices:[]int, Edges:[]tuple(int,int,int)):=IntegerWeightedGraph:
        Vertices := option{Vertices}
        Edges := option{Edges}
        AdjacencyList := option{BuildAdjacencyList[Vertices, Edges]}

    # Internal Constructor for float weighted graph
    BuildFloatWeightedGraphVE<constructor>(Vertices:[]int, Edges:[]tuple(int,int,float)):=FloatWeightedGraph:
        Vertices := option{Vertices}
        Edges := option{Edges}
        AdjacencyList := option{BuildAdjacencyList[Vertices, Edges]}

    # Generate edges for a random float weighted graph
    RandomFloatWeightedGraph<public>(Size:int, EdgeProbability:float, WeightLow:float, WeightHigh:float):[]tuple(int,int,float) =
        var Edges: []tuple(int,int,float) = array{}
        var Low:float = WeightLow
        var High:float = WeightHigh
        if (WeightLow > WeightHigh):
            set Low = WeightHigh
            set High = WeightLow
        for (Vertex1 := 1..Size, Vertex2 := 1..Size, Vertex1<>Vertex2):
                BernoulliRandomVariable := Probability.Distributions.Bernoulli(EdgeProbability)
                if (BernoulliRandomVariable = 1):
                    Weight := GetRandomFloat(Low, High)
                    set Edges += array{(Vertex1,Vertex2,Weight)}
        Edges

    # Generate edges for a random integer weighted graph
    RandomIntegerWeightedGraph<public>(Size:int, EdgeProbability:float, WeightLow:int, WeightHigh:int):[]tuple(int,int,int) =
        var Edges: []tuple(int,int,int) = array{}
        var Low:int = WeightLow
        var High:int = WeightHigh
        if (WeightLow > WeightHigh):
            set Low = WeightHigh
            set High = WeightLow
        for (Vertex1 := 1..Size, Vertex2 := 1..Size, Vertex1<>Vertex2):
                BernoulliRandomVariable := Probability.Distributions.Bernoulli(EdgeProbability)
                if (BernoulliRandomVariable = 1):
                    Weight := GetRandomInt(Low, High)
                    set Edges += array{(Vertex1,Vertex2,Weight)}
        Edges

    # Create a random integer weighted graph
    GenerateIntegerWeightedRandomGraph<public>(Size:int, EdgeProbability:float, WeightLow:int, WeightHigh:int):IntegerWeightedGraph =
        Vertices := for(Vertex := 1..Size):
            Vertex
        Edges := RandomIntegerWeightedGraph(Size, EdgeProbability, WeightLow, WeightHigh)
        BuildIntegerWeightedGraphVE(Vertices, Edges) 

    # Create a random integer weighted graph
    GenerateFloatWeightedRandomGraph<public>(Size:int, EdgeProbability:float, WeightLow:float, WeightHigh:float):FloatWeightedGraph =
        Vertices := for(Vertex := 1..Size):
            Vertex
        Edges := RandomFloatWeightedGraph(Size, EdgeProbability, WeightLow, WeightHigh)
        BuildFloatWeightedGraphVE(Vertices, Edges) 

    # Graph Algorithms
    Algorithms<public> := module:

        # Dijkstra's Algorithm for Shortest Path
        Dijkstra<public> := module:
            using { Heaps }

            INTEGER_MAX:int = 2147483647

            VertexInfo<public> := class:
                Key<public>:int = -1
                DistanceFromSource<public>:int = INTEGER_MAX
                Predecessor<public>:?VertexInfo = false

                GetKey<public>():int =
                    Key

                GetDistance<public>():int =
                    DistanceFromSource

                DebugString<public>()<transacts>:string =
                    if (DistanceFromSource = INTEGER_MAX):
                        "Key: {Key}, Distance: Inf"
                    "Key: {Key}, Distance: {DistanceFromSource}"

            # Get the full path to this vertex from source
            (VInfo:VertexInfo).ResolvePredecessorChain<public>()<transacts>:[]int =
                var PredecessorChain: []int = array{VInfo.Key}
                var CurrentVertex: VertexInfo = VInfo
                loop:
                    if (Predecessor := CurrentVertex.Predecessor?):
                        set CurrentVertex = Predecessor
                        set PredecessorChain += array{CurrentVertex.Key}
                    else:
                        break
                PredecessorChain

            # ToString for vertex info array
            (InfoArray:[]VertexInfo).PrintVertexInfo<public>()<transacts>:void =
                for (Vertex:InfoArray):
                    Print(Vertex.DebugString())

            # Less than helper for vertex info
            VertexInfoLessThan<public>(U:VertexInfo, V:VertexInfo)<decides><transacts>:void =
                U.DistanceFromSource < V.DistanceFromSource

            # Equivalent helper for vertex info
            VertexInfoEquivalent<public>(U:VertexInfo, V:VertexInfo)<decides><transacts>:void =
                U.DistanceFromSource = V.DistanceFromSource

            # Find vertex info element by key
            (InfoArray:[]VertexInfo).FindByKey<internal>(Key:int)<transacts>:VertexInfo =
                var ReturnInfo: VertexInfo = VertexInfo{}
                for(VInfo:InfoArray):
                    if (VInfo.Key = Key):
                        set ReturnInfo = VInfo
                ReturnInfo

            # Get index of vertex info in array
            (InfoArray:[]VertexInfo).GetIndex<internal>(Vertex:VertexInfo)<transacts>:int =
                var ReturnIndex: int = -1
                for (Index:=0..InfoArray.Length):
                    if (InfoArray[Index].Key = Vertex.Key):
                        set ReturnIndex = Index
                ReturnIndex

            # Remove vertex info by key
            (InfoArray:[]VertexInfo).RemoveByKey<internal>(Key: int)<transacts>: []VertexInfo =  
                for (VInfo:InfoArray, VInfo.Key<>Key):
                    VInfo

            # Relax the Destination vertex.
            #       If the path to Destination going through Source is shorter than going directly to Destination, add Source to the shortest path route
            Relax<internal>(Source: VertexInfo, Destination: VertexInfo, Weight: int)<transacts>: VertexInfo =
                var NewVertexInfo: VertexInfo = Destination
                if (Destination.DistanceFromSource > Source.DistanceFromSource + Weight):
                    set NewVertexInfo = VertexInfo{Key := Destination.Key, DistanceFromSource := Source.DistanceFromSource + Weight, Predecessor := option{Source}}
                NewVertexInfo

            # Initialize the shortest path from Source to every other vertex in the graph
            #       Every path has inifinite weight except from source to itself
            (Graph:IntegerWeightedGraph).InitializeSingleSource<internal>(Source:int)<transacts>:[]VertexInfo =
                var ReturnArray: []VertexInfo = array{}
                if (Vertices := Graph.GetVertices[]):
                    for (Vertex:Vertices):
                        if (Vertex=Source):
                            set ReturnArray += array{VertexInfo{Key := Vertex, DistanceFromSource := 0, Predecessor := false}}
                        else:
                            set ReturnArray += array{VertexInfo{Key := Vertex, DistanceFromSource := INTEGER_MAX, Predecessor := false}}
                ReturnArray

            # Implementation of Dijkstra's Algorithm for finding the shortest path through a graph from a single source vertex
            #   Cormen, Thomas H.; Leiserson, Charles E.; Rivest, Ronald L.; Stein, Clifford. Introduction to Algorithms (3rd Ed.) pg. 658, MIT Press.
            (Graph:IntegerWeightedGraph).Dijkstra<public>(Source: int)<transacts>: []VertexInfo =
                # Initialize single source, vertex set, and heap of vertices with cost of path from source
                var VertexInfoList:[]VertexInfo = Graph.InitializeSingleSource(Source)
                var VertexSet:[]VertexInfo = array{}
                var VertexHeap:MinHeap(VertexInfo) = MakeMinHeap(VertexInfoList, VertexInfoLessThan, VertexInfoEquivalent)
                # Loop through the heap, extracting the minimum cost edge each time
                loop:
                    if (HeapMinTuple := VertexHeap.ExtractMin[], set VertexHeap = HeapMinTuple(0)):
                        CurrentVertexInfo: VertexInfo = VertexInfoList.FindByKey(HeapMinTuple(1).Key)
                        set VertexSet += array{CurrentVertexInfo}
                        # Loop through the adjacency list of the Current Vertex and determine if the path to each Adjacent Vertex from the source
                        # is shorter if we go through the Current Vertex first. If it is, update the Vertex Info and the Heap
                        if (AdjacencyList := Graph.GetAdjacencyList[]):
                            for (Vertex : AdjacencyList[CurrentVertexInfo.Key], AdjacentVertexInfo := VertexInfoList.FindByKey(Vertex(0))):
                                UpdatedAdjacentVertexInfo: VertexInfo = Relax(CurrentVertexInfo, AdjacentVertexInfo, Vertex(1))
                                set VertexInfoList = VertexInfoList.RemoveByKey(Vertex(0)) + array{UpdatedAdjacentVertexInfo}
                                # Delete the old vertex info and insert the new vertex info
                                if (VertexHeapTemp := VertexHeap.DeleteKey[AdjacentVertexInfo]):
                                    set VertexHeap = VertexHeapTemp.InsertKey(UpdatedAdjacentVertexInfo)
                    # The heap is empty
                    else:
                        break
                VertexSet


Probability<public> := module:

    Distributions<public> := module:

        # P(X = 1) = p, P(X = 0) = 1-p
        Bernoulli<public>(p:probability):int = 
            Bp := GetRandomFloat(0.0, 1.0)
            if:
                Bp <= p
            then:
                1
            else:
                0
file_2.verse
Arrays<public> := module:

    <# Array utility to swap the elements contained in indices I and J #>
    (Array:[]t where t:type).Swap<public>(FirstIndex:int, SecondIndex:int)<decides><transacts>:[]t =
        ArrayTemp := Array.ReplaceElement[FirstIndex, Array[SecondIndex]]
        return ArrayTemp.ReplaceElement[SecondIndex, Array[FirstIndex]]


Heaps<public> := module:

    using { Arrays }

    MinHeap<public>(t:type) := class<concrete>:

        # Properties 
        Heap<internal>:[]t = array{}
        Size<internal>:int = 0
        LessThan<internal>:?type{_(:t,:t)<decides><transacts>:void} = false
        Equivalent<internal>:?type{_(:t,:t)<decides><transacts>:void} = false

        # Get the size of the heap array
        GetSize<public>()<transacts>:int =
            Size

        # Get a copy of the heap array 
        GetHeap<public>()<transacts>:[]t =
            Heap

        # Get the less than comparison function
        # Fails if no less than specified, succeeds and returns the function if specified
        GetLessThan<public>()<decides><transacts>:type{_(:t,:t)<decides><transacts>:void} =
            LessThan?

        # Get the equivalent comparison function
        # Fails if no equivalent specified, succeeds and returns the function if specified
        GetEquivalent<public>()<decides><transacts>:type{_(:t,:t)<decides><transacts>:void} =
            Equivalent?
   
        # Get the minimum value in the heap
        # Fails if heap is empty, succeeds and returns minimum value otherwise
        GetMin<public>()<decides><transacts>: t =
            Heap[0]

        # Get the index in the heap array of the element with the given key
        # Fails if key is not found, succeeds and returns the index key is found
        GetIndex<public>(Key:t)<decides><transacts>:int =
            var ReturnIndex:?int = false
            var LoopIndex:int = 0
            # Traverse the array linearly to find the index of the provided key
            loop:
                if (LoopIndex = Size):
                    break
                else:
                    if (Equivalent?[Heap[LoopIndex], Key]):
                        set ReturnIndex = option{LoopIndex}
                        break
                set LoopIndex += 1
            ReturnIndex?

        # Get the element key of the element at index ElementIndex
        # Fails if ElementIndex is either negative or greater than the size of the array, succeeds otherwise
        GetKey<public>(ElementIndex:int)<decides><transacts>:t =
            Heap[ElementIndex]

        # Get the index of the parent of the element at index ElementIndex
        # Should not fail
        Parent<public>(ElementIndex:int)<decides><transacts>:int =
            Floor((ElementIndex - 1) / 2)

        # Get the index of the left child of the element at index ElementIndex
        Left<public>(ElementIndex:int)<transacts>: int =
            (2 * ElementIndex) + 1

        # Get the index of the right child of the element at index ElementIndex
        Right<public>(ElementIndex: int)<transacts>:int =
            (2 * ElementIndex) + 2

        # Extract the minimum value from the Heap and return resultant Heap 
        ExtractMin<public>()<decides><transacts>:tuple(MinHeap(t), t) =
            # Get the minimum value, move the last value in the heap to the front of the heap array
            HeapMin := Self.GetMin[]
            var NewHeapArr:[]t = Self.Heap
            NewRoot := NewHeapArr[NewHeapArr.Length - 1]
            set NewHeapArr[0] = NewRoot
            NewArrTemp := NewHeapArr.RemoveElement[NewHeapArr.Length - 1]
            set NewHeapArr = NewArrTemp
            ReturnHeap:MinHeap(t) = MinHeap(t):
                MakeMinHeap<constructor>(Self)
                Heap := NewHeapArr
                Size := NewHeapArr.Length
            # Heapify the first value in the array and return this new heap and the previous minimum value
            if (ReturnHeap.GetSize() > 0):
                (ReturnHeap.Heapify[0], HeapMin)
            else:
                (ReturnHeap, HeapMin)

        # Decrease the value of the key located in position Index to value Key and return resultant Heap 
        # Succeeds if `0 <= ElementIndex < Self.Size`
        DecreaseKey<public>(ElementIndex:int, Key:t)<decides><transacts>:MinHeap(t) =
            # Decrease the value of the element in index ElementIndex to the new value Key
            var CurrentKey:int = ElementIndex
            var NewHeapArr:[]t = Self.Heap
            set NewHeapArr[ElementIndex] = Key
            # Decreaseing the value of the element's key might break the heap property
            # Since the Key is decreased, the element might need to move higher in the tree
            # Start with the current position of the element and move up the tree until
            # the heap property is satisfied
            loop:
                if:
                    CurrentKey = 0 or
                    LessThan?[NewHeapArr[Parent[CurrentKey]], NewHeapArr[CurrentKey]] or
                    Equivalent?[NewHeapArr[Parent[CurrentKey]], NewHeapArr[CurrentKey]]
                then:
                    break
                else:
                    if (KeyTmp := Parent[CurrentKey], HeapArrTemp := NewHeapArr.Swap[CurrentKey, KeyTmp]):
                        set NewHeapArr = HeapArrTemp
                        set CurrentKey = KeyTmp
                    else:
                        break
            MinHeap(t):
                MakeMinHeap<constructor>(Self)
                Heap := NewHeapArr

        # Delete the key at the given index while maintaining the Heap Property and return resultant heap
        # Succeeds if `0 <= ElementIndex < Self.Size`
        DeleteKeyAtIndex<public>(ElementIndex:int)<decides><transacts>:MinHeap(t) =
            # Decrease the value of the key at Index to the minimum value, extract that value, then return the resulting heap
            Self.DecreaseKey[ElementIndex, Self.GetMin[]].ExtractMin[](0)

        # Delete the first instance of this Key from the heap and return resultant heap 
        # Fails if the heap does not contain an element with key Key
        DeleteKey<public>(Key:t)<decides><transacts>:MinHeap(t) =
            Self.DeleteKeyAtIndex[Self.GetIndex[Key]]

        # Insert the given Key into the heap while maintaining the Heap Property and return resultant heap
        InsertKey<public>(Key:t)<transacts>:MinHeap(t) =
            # Insert the new key at the end of the heap's array
            var NewHeapArr:[]t = Self.Heap + array{Key}
            var ElementIndex:int = NewHeapArr.Length - 1
            # Traverse the heap tree from the bottom up starting with the newly inserted element
            # swapping the newly inserted element with its parent if it violates the heap property
            # Terminate this process and break the loop once the heap property is satisfied
            loop:
                if:
                    ElementIndex > 0
                    ParentIndex := Parent[ElementIndex]
                    Self.LessThan?[NewHeapArr[ElementIndex], NewHeapArr[ParentIndex]]
                    HeapArrTemp := NewHeapArr.Swap[ParentIndex, ElementIndex]
                then:
                    set NewHeapArr = HeapArrTemp
                    set ElementIndex = ParentIndex
                else:
                    break
            MinHeap(t):
                MakeMinHeap<constructor>(Self)
                Heap := NewHeapArr
                Size := NewHeapArr.Length

        # Construct a heap by positioning the element in index i in the proper location to maintain heap property
        # Heapify correctly places the element at index ElementIndex in the subtree rooted at index ElementIndex
        # Succeeds if `0 <= ElementIndex < Self.Size`
        Heapify<public>(ElementIndex:int)<decides><transacts>:MinHeap(t) =
            var Smallest:int = ElementIndex
            var NewHeapArr:[]t = array{}
            SmallestElement:t = Self.Heap[ElementIndex]
            LeftNode:int = Left(ElementIndex)
            RightNode:int = Right(ElementIndex)
            # If the element at index ElementIndex has a left child and the left child is smaller
            # update the index of the smallest element to the left child index
            if (LeftNode < Size, LessThan?[Self.Heap[LeftNode], SmallestElement]):
                set Smallest = LeftNode
            # If the element at the index of the right child is smaller than the index of the smaller 
            # of ElementIndex and the left child update the index of the smallest element to the right child index
            if (RightNode < Size, LessThan?[Self.Heap[RightNode], Self.Heap[Smallest]]):
                set Smallest = RightNode
            # If the smallest element index is not the element that we started with, swap the element with whichever
            # child was determined to be smaller, create a new heap after the swap, then heapfiy the
            # subtree rooted at the smaller of the two children
            if (Smallest <> ElementIndex, HeapArrTemp := Self.Heap.Swap[Smallest, ElementIndex]):
                set NewHeapArr = HeapArrTemp
                NewHeap := MinHeap(t):
                    MakeMinHeap<constructor>(Self)
                    Heap := NewHeapArr
                return NewHeap.Heapify[Smallest]
            else:
                return Self

    # Construct a heap from an array, ordering function, and equivalence function
    MakeMinHeap<public><constructor>(
        HeapIn:[]t,
        LessThan:type{_(:t,:t)<decides><transacts>:void},
        Equivalent:type{_(:t,:t)<decides><transacts>:void} where t:type
    )<transacts> := MinHeap(t):
        # Define variables for the block portion of the constructor
        let:
            var NewHeapArr: MinHeap(t) = MinHeap(t):
                Heap := HeapIn
                Size := HeapIn.Length
                LessThan := option{LessThan}
                Equivalent := option{Equivalent}
            var Start:int = 0
        # Heapify the array starting at the bottom and working up the tree to the root
        block:
            if (StartTemp := Floor(HeapIn.Length / 2), set Start = StartTemp):
                for (Index := 0..Start):
                    if (HeapArrTemp := NewHeapArr.Heapify[Start - Index]):
                        set NewHeapArr = HeapArrTemp
        Heap := NewHeapArr.GetHeap()
        Size := HeapIn.Length
        LessThan := option{LessThan}
        Equivalent := option{Equivalent}

    # Construct a copy of a heap from an existing heap
    MakeMinHeap<public><constructor>(HeapIn: MinHeap(t) where t:type)<transacts> := MinHeap(t):
        Heap := HeapIn.Heap
        Size := HeapIn.Size
        LessThan := HeapIn.LessThan
        Equivalent := HeapIn.Equivalent

    # Heapsort array of any type.
    # Worst Case:   O(n log n)
    # Average:      O(n log n)
    Heapsort<public>(
        ArrayIn:[]t,
        LessThan:type{_(:t,:t)<decides><transacts>:void},
        Equivalent:type{_(:t,:t)<decides><transacts>:void} where t:type
    )<transacts>:[]t =
        # Construct a min heap from the input array
        var NewHeapArr:MinHeap(t) = MakeMinHeap(ArrayIn, LessThan, Equivalent)
        var ReturnArray:[]t = array{}
        # Extract the minimum of the array until the array is empty
        for (Element : NewHeapArr.GetHeap()):
            if (HeapMinTuple := NewHeapArr.ExtractMin[]):
                set NewHeapArr = HeapMinTuple(0)
                set ReturnArray += array{HeapMinTuple(1)}
        ReturnArray
graph_test.verse
using { /UnrealEngine.com/Temporary/Diagnostics }

log_graph_test := class(log_channel):

# A project-wide "Logger" to print messages from functions that are not in a class with a log.
GraphLog<public>(Message:[]char, ?Level:log_level = log_level.Normal)<transacts>:void=
    Logger := log{Channel := log_graph_test}
    Logger.Print(Message, ?Level := Level)

using { /Fortnite.com/Devices }
using { Graphs.Algorithms.Dijkstra }

# Graph Tests
graph_test := class(creative_device):

    RunGraphTest<private>(TestDescription:string, Graph:Graphs.IntegerWeightedGraph, SourceVertex:int, ExpectedResult:[]VertexInfo)<decides><transacts>:void=
        GraphLog("Testing: {TestDescription}")
        GraphLog("Graph:\n {Graph.DebugString()}")
        SourceResult:[]VertexInfo = Graph.Dijkstra(SourceVertex)
        GraphLog("Dijkstra's algorithm with source vertex {SourceVertex}:")
        SourceResult.PrintVertexInfo()
        for (Source:SourceResult, Expected:ExpectedResult, Source.Key=Expected.Key):
            Source.DistanceFromSource=Expected.DistanceFromSource

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

        # Connected Graph with 9 vertices and 14 edges
        Graph0:Graphs.IntegerWeightedGraph = Graphs.BuildIntegerWeightedGraph(
            map:
                0 => array{(1,4), (7,8)}
                1 => array{(0,4), (7,11), (2,8)}
                2 => array{(1,8), (3,7), (5,4), (8,2)}
                3 => array{(2,7), (4,9), (5,14)}
                4 => array{(3,9), (5,10)}
                5 => array{(2,4), (3,14), (4,10), (6,2)}
                6 => array{(5,2), (7,1), (8,6)}
                7 => array{(0,8), (1,11), (6,1), (8,7)}
                8 => array{(2,2), (6,6), (7,7)}
        )

        # Result sourced from vertex 0
        ExpectedResult0:[]VertexInfo = array:
            VertexInfo{Key:=0, DistanceFromSource:=0}
            VertexInfo{Key:=1, DistanceFromSource:=4}
            VertexInfo{Key:=2, DistanceFromSource:=12}
            VertexInfo{Key:=3, DistanceFromSource:=19}
            VertexInfo{Key:=4, DistanceFromSource:=21}
            VertexInfo{Key:=5, DistanceFromSource:=11}
            VertexInfo{Key:=6, DistanceFromSource:=9}
            VertexInfo{Key:=7, DistanceFromSource:=8}
            VertexInfo{Key:=8, DistanceFromSource:=14}

        if:
            RunGraphTest["Connected graph on 9 vertices with 14 edges with source vertex 0", Graph0, 0, ExpectedResult0]
        then:
            GraphLog("All tests passed")
        else:
            GraphLog("One or more tests failed")
Sign in to download module

Copy-paste each file above is always free.

Comments

    Sign in to vote, comment, or suggest an edit. Sign in
    📄
    Source
    @VerticesIn
    Epic Games Community
    @VerticesIn

    Created by a member of the Epic Games community. Rights remain with the original author, under Epic's community content terms. Terms ↗

    View original Sources & licensing
    Request removal
    Last updated Jun 23, 2026
    Verse module (3 files)
    Build failed · 28 errors

    Download the full module (zip) from the code panel above.

    Keep exploring
    More in Verse Language · 2 of 106
    Prev
    fortnite float to int cast and operators
    Next
    fortnite shuffle the array
    Related topics
    • Fortnite Fort Round Gameplay Interface For Scene Graph Components Ui
    • Twinmagsmg Br Ch4s1 Epic Weapons
    • Fortnite Reverse Array Verse Language
    • Item Machine Smg Epic Items
    • scenegraph Scene Graph

    Related

    Open in graph →

    Related topics

    • Fortnite Fort Round Gameplay Interface For Scene Graph Components
    • Twinmagsmg Br Ch4s1 Epic
    • Fortnite Reverse Array
    • Item Machine Smg Epic
    • scenegraph
    VerseIsland · an archipelago of Verse & UEFN knowledge
    🗺️ Island atlas Learn Guides History About & Press Sources & Licensing Status

    Not affiliated with Epic Games. Fortnite, UEFN, Unreal Engine, and Verse are trademarks of Epic Games, Inc. Content is attributed to its source — see Sources & Licensing.

    🦜

    Scout · your island guide

    The Isle of Verse