These files compile together (same module folder).
file_1.verse
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/SpatialMath }
# A Verse-authored creative device that can be placed in a level.
# This device is the game manager.
caterpillar_commander<public> := class(creative_device):
@editable
Character<private>:game_character = game_character{}
@editable
Gameboard<private>:gameboard = gameboard{}
@editable
GameLoopWait<private>:float = 1.75
UIManager<private>:ui_manager = ui_manager{}
# Runs when the device is started in a running game.
OnBegin<override>()<suspends>:void=
Setup()
GameLoop()
Setup<private>():void=
Players := GetPlayspace().GetPlayers()
# Set first player as damager for character.
MaybePlayer:?player = option{Players[0]}
Character.SetPlayerAsDamageInstigator(MaybePlayer)
for (Player : Players):
UIManager.Create(Player)
UIManager.Draw(Player)
Cleanup<private>():void=
Playspace := GetPlayspace()
for (Player : Playspace.GetPlayers()):
UIManager.Remove(Player)
GameLoop<private>()<suspends>:void=
CharacterStart := Gameboard.GetCharacterStart()
if (Character.MoveToStart[CharacterStart]):
race:
loop:
Command := UIManager.WaitForPlayerSelection()
Execute(Character, Gameboard.TileSize, Command)
Sleep(GameLoopWait)
Gameboard.WaitForEndGoal()
Cleanup()
file_2.verse
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/SpatialMath }
# Type of commands to give the game character
command<internal> := enum:
Forward
TurnRight
TurnLeft
None
ToString<internal>(Command: command):string =
case(Command):
command.Forward => "Forward"
command.TurnRight => "TurnRight"
command.TurnLeft => "TurnLeft"
command.None => "None"
Execute<internal>(Character:game_character, TileSize:vector3, Command:command)<suspends>:void=
Print("{Command}")
case(Command):
command.Forward =>
Character.Forward(TileSize)
command.TurnRight =>
Character.TurnRight()
command.TurnLeft =>
Character.TurnLeft()
_ =>
Print("Default command case")
file_3.verse
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/SpatialMath }
game_character<internal> := class<concrete>:
MoveToStart<public>(Location:vector3, Rotation:rotation)<decides><transacts>:void=
InGameRep.TeleportTo[Location, Rotation]
Forward<public>(TileSize:vector3)<suspends>:void=
var Transform:transform = InGameRep.GetTransform()
LocalForward := Transform.Rotation.GetLocalForward()
if(Abs(LocalForward.X) >= Abs(LocalForward.Y)):
set Transform.Translation.Y += Sgn(LocalForward.X) * TileSize.X
else:
set Transform.Translation.X += -Sgn(LocalForward.Y) * TileSize.Y
InGameRep.MoveTo(Transform, MoveDuration)
Damage()
TurnRight<public>()<suspends>:void=
var Transform:transform = InGameRep.GetTransform()
set Transform.Rotation = Transform.Rotation.ApplyLocalRotationZ(DegreesToRadians(90.0))
InGameRep.MoveTo(Transform, MoveDuration)
TurnLeft<public>()<suspends>:void=
var Transform:transform = InGameRep.GetTransform()
set Transform.Rotation = Transform.Rotation.ApplyLocalRotationZ(DegreesToRadians(-90.0))
InGameRep.MoveTo(Transform, MoveDuration)
SetPlayerAsDamageInstigator<public>(InPlayer:?player):void=
set DamageInstigator = InPlayer
@editable
InGameRep<private>:creative_prop = creative_prop{}
@editable
Damager<private>:explosive_device = explosive_device{}
@editable
MoveDuration<private>:float = 0.5
var DamageInstigator<private>:?agent = false
Damage<private>():void=
if (Instigator := DamageInstigator?):
Damager.Explode(Instigator)
Damager.Reset()
file_4.verse
using { /Fortnite.com/Devices }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org/Simulation }
using { /Verse.org/Simulation/Tags }
gameboard<internal> := class<concrete>:
# The size of each tile on the gameboard. By default the default Fortnite
# tile size of 512x512x384.
@editable
TileSize<public>:vector3 = vector3{X:=512.0, Y:=512.0, Z:=384.0}
WaitForEndGoal<public>()<suspends>:void=
EndGoal.TriggeredEvent.Await()
GetCharacterStart<public>():tuple(vector3, rotation)=
(CharacterStart.Translation, CharacterStart.Rotation)
@editable
CharacterStart<private>:transform = transform{}
# End position goal for the character
@editable
EndGoal<private>:trigger_device = trigger_device{}
file_5.verse
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /Fortnite.com/UI }
using { /UnrealEngine.com/Temporary/UI }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org/Colors }
ui_manager<internal> := class:
Create<public>(Player:player):void=
# Command Buttons
ButtonForward:button_regular = button_regular:
DefaultText := ForwardText
ButtonTurnRight:button_regular = button_regular:
DefaultText := TurnRightText
ButtonTurnLeft:button_regular = button_regular:
DefaultText := TurnLeftText
ButtonForward.OnClick().Subscribe(OnForwardSelected)
ButtonTurnRight.OnClick().Subscribe(OnTurnRightSelected)
ButtonTurnLeft.OnClick().Subscribe(OnTurnLeftSelected)
# Canvas represents the full screen.
# Verse UI is hierarchical, so nest relevant elements together.
# Appears in lower middle of screen
ButtonsCanvas := canvas:
Slots := array:
canvas_slot:
Anchors := anchors:
Minimum := vector2{X := 0.5, Y := 1.0}
Maximum := vector2{X := 0.5, Y := 1.0}
Offsets := margin:
Top := 0.0
Left := 0.0
Right := 0.0
Bottom := 0.0
Alignment := vector2:
X := 0.5
Y := 1.0
SizeToContent := true
Widget := stack_box:
Orientation := orientation.Horizontal
Slots := array:
stack_box_slot:
Widget := ButtonForward
stack_box_slot:
Widget := ButtonTurnRight
stack_box_slot:
Widget := ButtonTurnLeft
if (set CanvasPerPlayer[Player] = ButtonsCanvas):
# Adds the buttons to the screen for this player.
Draw<public>(Player:player):void=
if:
PlayerUI := GetPlayerUI[Player]
Canvas := CanvasPerPlayer[Player]
then:
PlayerUI.AddWidget(Canvas, player_ui_slot{InputMode := ui_input_mode.All})
# Removes the buttons from the screen for this player.
Remove<public>(Player:player):void=
if:
PlayerUI := GetPlayerUI[Player]
Canvas := CanvasPerPlayer[Player]
then:
PlayerUI.RemoveWidget(Canvas)
# Waits for the player to select one of the commands.
# Result is the command the player selected.
WaitForPlayerSelection<public>()<suspends>:command=
CommandEvent.Await()
var CanvasPerPlayer<private>:[player]canvas = map{}
CommandEvent<private>:event(command) = event(command){}
ForwardText<private><localizes>:message = "Forward"
TurnRightText<private><localizes>:message = "Turn Right"
TurnLeftText<private><localizes>:message = "Turn Left"
# Signal the turn left command when player selects turn left in UI.
OnTurnLeftSelected<private>(Message:widget_message):void=
CommandEvent.Signal(command.TurnLeft)
# Signal the turn right command when player selects turn right in UI.
OnTurnRightSelected<private>(Message:widget_message):void=
CommandEvent.Signal(command.TurnRight)
# Signal the forward command when player selects forward in UI.
OnForwardSelected<private>(Message:widget_message):void=
CommandEvent.Signal(command.Forward)