1 Kasım 2024’te yayınlanan 32.00 sürümünden itibaren Verse dilini Sürüm 1 olarak stabil hale getiriyoruz. Hem stabilite için hem de gelecekteki Verse dili güncellemelerinde kodunu kademeli olarak yükseltmen daha kolay olacağından, projeni yükseltmeni öneririz. Bu yükseltme isteğe bağlıdır; projenin geçerli sürümü her zaman daha eski bir Verse sürümünde çalışmaya devam eder. Bununla birlikte, ileride Verse’ün daha yeni bir yinelemesini yüklemek istediğinde bir noktada projeni yükseltmen gerekebilir.
İlk genel sürümünden bu yana Verse dilini geliştirmeye ve eklemeler yapmaya devam ettik. Bu değişiklikler, kullanıcıların yeni bir dil sürümüne yükseltmesini gerektirmeksizin şeffaf bir şekilde yayınlandı. Çoğu dil değişikliğinin, dilin önceki sürümlerinin altyapısıyla uyumlu olacak şekilde yapılarak, UEFN’in yeni sürümleriyle kullanıcılara ulaştırılmaya devam edeceğini umuyoruz.
Ancak bazı dil değişiklikleri geriye dönük uyumlu değildir ve derlenebilmesi için kodunda değişiklikler yapılması gerekli olabilir. Bu tür geriye dönük uyumsuz değişiklikler, yalnızca kullanıcı projesini yeni dil sürümüne yükselttiğinde tetiklenecektir.
Geriye dönük uyumlu olmayan kodu her kaydettiğinde, kod davranışının dilin yeni sürümlerinde kullanımdan kaldırıldığını gösteren uyarılar görüntülenir. Örneğin, Verse Dili’nin yeni sürümüyle uyumlu olmayan kodlama uygulamalarını kullanmaya devam etmek, kodla ilgili uyarılara yol açar.
Projen V0’da herhangi bir kullanımdan kaldırma uyarısı olmadan derlenirse kodunun davranışında herhangi bir değişiklik yapmadan V1’e yükseltebilirsin. UEFN 32.00’de bir V0 projesini açtığında ve kodun herhangi bir hata veya uyarı almadan derlendiğinde editör, yeni sürüme geçmek isteyip istemediğini sorar.

Daha sonra herhangi bir nedenle yeni sürüme geçmek veya eski sürüme düşürmek istersen bunu proje ayarlarından yapabilirsin.
Click image to enlarge.
Proje dosyalarını Fortnite Projeler klasöründen de açabilir ve .uplugin dosyalarının Verse sürümünü değiştirebilirsin.
Click image to enlarge.
Kullanımdan kaldırılanların çoğu, dilde ileride yapılacak iyileştirmelerin önünü açmaya yöneliktir ve kullanıcılara henüz bir fayda sağlamaz. Bunun iki istisnası, yerel niteleyiciler ve yapı karşılaştırmasıdır.
V1’deki Değişiklikler
Set İfadesinde Başarısızlık
Bir set
ile yürütülen ifadenin artık başarısız olmasına izin verilmiyor. Daha önce,
F():void=
var X:int = 0
set X = FailableExpression[]
koduna izin veriliyordu ve X
değeri, FailableExpression
’ın değerlendirildiği değere ayarlanır ve bir uyarı meydana gelirdi. V1’de buna izin verilmiyor.
Kodunu düzeltmek için ifadenin başarısız olamayacağından emin olman gerekir. Bunu yapabilmenin bir yolu, aşağıdaki değişikliği yapmaktır:
var X:int = 0
Value:= FailableExpression[] or DefaultValue
set X = Value
Harita Değişmez Anahtarlarında Başarısızlık
Daha önce, bir haritadaki değişmez anahtarlar başarısız olabilirdi:
map{ExpressionThatCannotFail=>Value}
Bunun basit bir örneği map{ (0 = 0) =>0 }
ifadesidir; burada 0 = 0
başarısız olur. Buna artık izin verilmiyor.
Bloklar İçin Noktalı Virgül/Virgül/Satır Başı Ayırıcılarını Karıştırma
Daha önce alt ifadeleri ayırmak için noktalı virgül/virgül/satır başı ayırıcılarının karma kullanımına izin veriliyor ve bu, kodda aşağıda gösterilen sonuca yol açıyordu:
A,
B
for (A := 0..2):
# more code here
Bu kod, dahili olarak fazlalıklardan arındırılıp aşağıda gösterildiği gibi yeniden kodlanıyordu:
block:
A
B
for (A := 0..2):
# more code here
Bu, kod bloğunda A
’nın her iki tanımının birbiriyle çakışmadığı, çünkü kendi ayrı kapsamına sahip örtük bir blok oluşturulduğu anlamına geliyordu.
Ancak bu yanlış bir davranıştır ve en son Verse dili sürümünde düzeltilmiştir. Şimdi aynı kod her alt ifadeyi ayrı ayrı ele alacak ve aşağıdaki durum ortaya çıkacaktır:
A
B
for (A := 0..2):
# more code here
Bu, birinci A
ile ikinci A := 0..2
tanımının artık birbirini gölgelediği anlamına gelir ve anlam belirsiz olur.
Bu sorunu çözmek için içerik üreticilerinin (ve bu davranışı kullanan herkesin) tüm Verse kodlarında alt ifadeleri ayırmak için noktalı virgül/virgül/satır başlarını karıştırmayı bırakması gerekiyor.
Example:
PropPosition := Prop.GetTransform().Translation,
if(Round[PropPosition.Z] = Round[ROOT_POSITION.Z]) { break }
Sleep(0.0)
Şu şekilde değiştirilmelidir:
PropPosition := Prop.GetTransform().Translation # note the trailing comma here has been removed
if(Round[PropPosition.Z] = Round[ROOT_POSITION.Z]) { break }
Sleep(0.0)
Daha önce, “28.20”den itibaren herhangi bir karışık ayırıcı algılandığında bir uyarı veriliyordu. Buna artık Verse dilinin en son sürümünde izin verilmiyor.
Benzersiz Belirtici Değişiklikleri
Artık <unique>
belirticisine sahip sınıflar <allocates>
oluşturma efektini gerektiriyor. Örneğin class<unique><computes>
ifadesine artık izin verilmiyor.
Fonksiyon-Yerel Niteleyiciler
(local:)
niteleyicisi, diğer tanımlayıcılardan ayırt edip belirginleştirmek için fonksiyonların içindeki tanımlayıcılara uygulanabilir.
For example:
ExternallyDefinedModuleB<public> := module:
ShadowX<public>:int = 10 # Yalnızca `ModuleC` yayınlandıktan sonra eklenir.
ModuleC := module:
using{ExternallyDefinedModuleB}
FooNoLocal():float=
ShadowX:float = 0.0
ShadowX
ShadowX
belirsiz olduğundan (ExternallyDefinedModuleB.ShadowX
’ten mi yoksa FooNoLocal
içinde ShadowX
’ten mi?) yukarıdaki kod bir gölgeleme hatasına yol açacaktır.
Bunu çözmek için aşağıdaki örnekte olduğu gibi hangi ShadowX
’e başvurulduğunu netleştirmek için (local:)
niteleyicisini kullanabilirsin:
ExternallyDefinedModuleA<public> := module:
ShadowX<public>:int = 10 # Yalnızca `ModuleB` yayınlandıktan sonra eklenir.
ModuleB := modül:
using{ExternallyDefinedModuleA}
FooLocal():float=
(local:)ShadowX:float = 0.0 # Belirsizliği gidermek için burada `local` niteleyicisi kullanılabilir.
(local:)ShadowX
Daha önce, veri tanımı tanımlayıcı olarak local
sözcüğünü kullandığını tespit ettiğimizde bir uyarı oluşturuyorduk, çünkü bu ayrılmış bir anahtar sözcüktür. En son dil sürümünde local
kullanımı bir hataya neden olur ve local
tanımlayıcısını normal bir veri tanımı tanımlayıcısı olarak kullanmak istersen kullanımının açıkça nitelenmesi gerekir.
Aşağıda, başka bir yerel niteleyici örneği yer alıyor:
MyModule := modül:
X:int = 1
Foo((local:)X:int):int = (MyModule:)X + (local:)X
Bu örnekte (local:)
niteleyicisini belirtmemiş olsaydık Foo(X:int)
içindeki X
doğrudan yukarıdaki X:int = 1
tanımını gölgeleyecekti çünkü her iki X
tanımlayıcısı aynı kapsamdadır. Bu nedenle, (local:)
niteleyicisini kullanmak, Foo
’nun bağımsız değişken parametre yan tümcesindeki X
’i yalnızca Foo
kapsamına özel hale getirerek bu iki X
’in belirsizliğini gidermemize olanak sağlar. Aynı durum Foo
gövdesindeki X
tanımlayıcıları için de geçerlidir.
Yapılarda Herkese Açık Alanlar
Yapılar (struct
’lar) içindeki tüm alanlar artık herkese açık olmak zorunda. Varsayılan durumda, bu artık V1’den itibaren de geçerlidir (<public>
kullanmak artık gerekli değil).
V1 ayrıca iki struct
’ı karşılaştırma becerisini de sunuyor. Bir yapının tüm alanları karşılaştırılabilir ise yapının iki örneğini alan alana karşılaştırmak için =
kullanabilirsin. Örneğin:
vector3i := struct{X:int, Y:int, Z:int}
vector3i{X:=0, Y:=0, Z:=0} = vector3i{X:=0, Y:=0, Z:=0} # başarılı olur.
vector3i{X:=0, Y:=0, Z:=0} = vector3i{X:=0, Y:=0, Z:=1} # başarısız olur çünkü Z iki örnekte farklıdır.