Sunday 6 May 2018

A comparison between Orb-C, UnrealScript and QuakeC

Orb is the scripting module for Drift. It is hierarchical, object-oriented, and modular. The way it is integrated into the engine is more like Quake than Unreal, since the Unreal engine's scripts are very deeply linked with the native code.

The easiest way to compare these three scripting language are to present 3 functions written in each language, that do the exact same thing. But please remember that I am not fully competant with UnrealScript.

Here's the function in Orb-C:


function PlasmaGun::Fire()
{
 print("...\n");

 if(time > Owner.ReloadFinishTime)
 {
  print("FIRE!!!\n");

  PlasmaBolt P;
  P = new PlasmaBolt;
  
  P.Location = Owner.Location;
  P.Velocity = Owner.Direction * {5,5,5};
  
  Owner.ReloadFinishTime = time + 1;
 }
 
}

It should be obvious. An object of class PlasmaBolt is created, set to the weapon's owner's location, and pushed in a direction. A timer is set to control the rate of fire.

Here's the same thing again, but in QuakeC (in the style of the original Quake 1 prog sources):


void() plasmagun_fire = 
{
 local entity p;

 print ("...\n");
 
 if(time > owner.reloadfinished)
 {
  print ("FIRE!!!\n");
  
  p = spawn();
  
  missile.movetype = MOVETYPE_FLYMISSILE;
  missile.solid = SOLID_BBOX;
  
  p.classname="plasmabolt";
  
  p.velocity = owner.dir * 5;
  
  p.owner = self;

  p.touch = T_MissileTouch;

  setmodel (p, "progs/plasmabolt.mdl");
  setsize (p, '0 0 0', '0 0 0');  
  setorigin (p,owner.origin);
   
   
  owner.reloadfinished=time+1;
 }
 
}


Due to a lack of class definitions in QC, the function must be named specifically for the 'class'. Also, a lot of extra code is needed since there is no equivalent of the per-class main() function Orb-C has.

At this time, Orb-C vectors can only be multiplied by another vector. QC allows a single value to be the multiple. This is not hard to fix, I just haven't got round to it.

Now lets take a look at some UnrealScript.


function Fire()
{
 Log("...");
 
 if(Time > Owner.ReloadFinishTime)
 {
  Log("FIRE!!!");

  local PlasmaBolt P = Spawn(class'PlasmaBolt',,, Owner.Location);
  
  P.Velocity = Owner.Direction * 5;
  
  Owner.ReloadFinishTime = Time + 1;
 }
}


I'm not sure this is completely correct, but from looking at the UC sources exported from UnrealEd for Unreal Engine 1, this is basically what's needed.

You can probably see there's slightly less code, and it's not much different from Orb-C. You can't see it from this example, but UnrealScript has a lot more features than my scripting engine and language.

You may also notice that the function is simply called Fire(). This is because Unreal separates each class definition into it's own UC source file. There's no need to use a namespace since there won't be any definitions related to other classes in the entire text file.

So those people experienced in UnrealScript would pick up Orb-C very easily, but find less power at their disposal. I'll be brave and say that development with Orb-C is faster, but since it's development has some way to go, it's hard to put it in a real place right now.

I will post more information about the workings and usage of Orb in the near future.

No comments: