Jump to content
engima

[RELEASE] SQX Language - Object Oriented Scripting

Recommended Posts

WHAT IS SQX?

SQX is a script language that is used to create scripts and missions in Arma 3. SQX is very similar to SQF, but it has support for object oriented scripting.

 

PHILOSOPHY

SQX extends the SQF language primarily by adding control structures that allow for object oriented scripting. As such, plain SQF is allowed, but it also introduces support to organize the code into classes and inheritances. SQX also introduces a small toolbox of some optionally available new commands and keywords that may be helpful (such as the "return" statement). The SQX language reference explains all the ways that SQX differs from SQF. One could say that SQX is for SQF what TypeScript is for Javascript.

 

FEATURES OF SQX

  • True object orientation (objects and inheritence, virtuals and overrides)
  • Type handling and customizable types (classes, interfaces, enums)
  • Three different kinds of class members (fields, methods, properties)
  • Three different kinds of accessors (private, protected, public)
  • Support for statics (methods and properties)
  • Syntax close to SQF
  • Some new convenient commands (like "is", "as", "return" etc.)
  • Compiler synchronizes line numbers between SQX and SQF to support runtime error handling
  • SQX class objects can be broadcasted between machines
  • Complete reference documentation (at www.typesqf.com).


WHAT CAN YOU DO?
You can structure your code in an object oriented way, creating your own types and actions using classes, interfaces and enums. Well, these are just the tools. What you really can achieve is great structured code, easy to read, easy to write and easy to understand. It extends the boundaries of what code is possible to overview and control.

 

WHAT IS OBJECT ORIENTATION?

If you are a developer, you already know, and the reference documentation and general SQF resources should be enough. I you are not familiar with it then start with this Wikipedia article: https://en.wikipedia.org/wiki/Object-oriented_programming.

 

HOW TO GET STARTED?

  1. Download the TypeSqf Editor from www.typesqf.com.
  2. Create a new mission.
    • In Eden Editor in Arma 3, create a new mission and insert at least one playable unit.
    • In TypeSqf, select "Open mission" and select the newly created mission.sqm.
  3. Install the CPack TypeSqf.MissionTemplate.Mp.Standard.
    • In TypeSqf, open the CPack Console in the Tools menu.
    • Write "Install TypeSqf.MissionTemplate.Mp.Standard" and press ENTER. The mission template (written in SQX) is now installed into your mission.
  4. Compile and build the project and play the default template mission.
    • Compile the mission in TypeSqf by using "Compile project" on the Build menu.
    • Play the simple default mission.

 

MEDIA

The following video shows when I use SQX to create and use a Crowd object:

 

 

HOW DOES IT WORK?
A class instance variable (instantiated with the new keyword) is under the hood an SQF variable of type Array. The class instance's fields and properties are saved as array items in an order kept track of by the SQX compiler. Methods compiles into global functions, with the instance variable (the class array) sent in as the first parameter. This is of course all abstracted by the compiler and not visible to the developer. All SQX is written into .sqx files, and all .sqx files are then compiled into .sqx.sqf counterparts enabling them to be read and interpreted by Arma 3.

 

SOME IMPORTANT NOTES
A language limitation: Due to limitations in SQF arrays it is not possible to instantiate two classes that reference each other. I.e. a parent class can have children, but these children cannot contain references back to its parent. The solution is simply to avoid these kinds of structures, and if you still do it you will get a runtime error.

 

An editor limitation: The TypeSqf editor does not have complete autocompletion regarding SQX, but it helps with the most common stuff. E.g. it only suggests one level of chained properties and methods, and it suggests variable names by searching the whole file instead of the actual programming scope context. If you are an advanced developer, please remember that the SQX language does handle most of expected code structures, which is more than the editor will suggest.

 

THE TYPESQF EDITOR

Note that this forum is for the SQX Language, which is closely related to, but also separated from, the TypeSqf Editor. Please only post questions and comments regarding the SQX Language here. Questions and comments about the TypeSqf editor goes into the TypeSqf forum.

 

VERSION HISTORY

Version 1.07

-SQX: Support for multiline strings (thanks Josef!).

 

Version 1.06

-SQX: Fixed: Analyze of multiple class inheritence levels sometimes resulted in faulty error messages.

 

Version 1.05

-Fixed: Analyzer does not forget about file content in files that are being removed.

 

Version 1.03

-SQX: Refactor of SQF/SQX analyzer and compiler (speeded up the build times a lot).

-SQX: Now possible to declare typed variables on a single assignement line (private Scalar _number = 0).

-SQX: Now possible to declare typed variables using new SQX keyword 'var' (var _number = 0).

 

Version 1.02

-Fixed: Strange behavior regarding negation symbol (e.g. "return -1;").
-Fixed: No warning when sub class tries to override a method that does not exist in base class.

 

Version 1.01

  • SQX: Added checks for when a sub class is missing call to explicit base constructor.

 

Version 1.0

  • First version.
  • Like 7
  • Thanks 2

Share this post


Link to post
Share on other sites

I start out with a comment myself.

 

The TypeSqf editor and the SQX script language is something I just made for fun. It is not perfect (there will always be sharp edges to polish), but it is very good. At least regarding my own needs.

 

I’ve been working with them in parallell for quite some years. SQX has been a bit hidden in the back of the TypeSqf editor until now. But I think it has proven itself enough, so why not release it at last.

 

Well, if it is useful for someone else too, it would be awesome!

 

Happy coding!

  • Like 3

Share this post


Link to post
Share on other sites

New version: 1.01

  • SQX: Added checks for when a sub class is missing call to explicit base constructor.
  • Like 2

Share this post


Link to post
Share on other sites

Hi Engima, congratulations on creation of this SQF extension, I really like it, I hope that more people will turn to OOP SQF!

Me and my friends have been using our custom preprocessor-based implementation of SQF OOP, you can check example files made with it if you want: https://github.com/Sparker95/Vindicta/blob/GOAP-AI/Vindicta.Altis/OOP_Light/OOP_Light.h

Regarding the problem with parent-child references: arma doesn't allow recursive arrays, one possible solution would be like this: when we create an object, instead of making an array and returning this array to user directly, you could store the array in some unique variable in missionNamespace, and return that string. But it would mean that in your OOP created objects will not be auto-deleted when they go out of scope, like objects returned by classic C++ new operator.
Or maybe another solution, you could keep the current implementation of objects as structs which are passed by value and their life time is auto-manage and the one I proposed above as actual objects allocated in the heap? Overall, not being able to have a back-reference in an OOP language feels quite limiting.

Share this post


Link to post
Share on other sites

New version. Thanks to Josef who is helping me a lot with ideas and code structures!

 

Version 1.02

-Fixed: Strange behavior regarding negation symbol (e.g. "return -1;").
-Fixed: No warning when sub class tries to override a method that does not exist in base class.

Share this post


Link to post
Share on other sites

New version. Thanks Josef for good teamwork!

 

Version 1.03

-SQX: Refactor of SQF/SQX analyzer and compiler (speeded up the build times a lot).

-SQX: Now possible to declare typed variables on a single assignement line (private Scalar _number = 0).

-SQX: Now possible to declare typed variables using new SQX keyword 'var' (var _number = 0).

Share this post


Link to post
Share on other sites

New version.

 

Version 1.05

-Fixed: Analyzer does not forget about file content in files that are being removed.

Share this post


Link to post
Share on other sites

Hi @engima,

 

First, thanks for the nice work !

 

I believe that enabling OOP data structure to the SQF language is a HUGE step in making the scripting process more human-friendly.

 

I was wondering if you were planning to release the compiler as a CLI application allowing us to use our preferred IDE instead of TypeSqf. I'm mainly thinking about VSC. If so, it would be great to have a linter too.

 

I'm not really sure how it would work, but if it is possible to enable IntelliSense features on SQX, scripting would become way more fun.

 

Thanks again for your work, I can't wait to write my first scripts in SQX 🙂

Share this post


Link to post
Share on other sites

Hi @Rosetux

 

The step would not be huge. The TypeSqf project is already divided into two, where the editor is one part and the SQF and the SQX analyzer/compiler is the other. The interface between them is C# classes inside a DLL.

 

And the TypeSqf editor is already using intellisense for SQX, so that is possible too.

Share this post


Link to post
Share on other sites

New version.

 

Version 1.06

-SQX: Fixed: Analyze of multiple class inheritence levels sometimes resulted in faulty error messages.

Share this post


Link to post
Share on other sites

Hey @engima,

I'm working on a project using SQX and I was wondering if there's a way to initialize public static properties.

I'd like to use a public static property as a class constant, the issue is that there is no way to initialize property at class scope.

The documentation show how to initialize a property through the constructor, but the point of having it static is not to have to call the constructor.

As a workaround I'm using a static method returning a literal string

1604875494-capture.png

Thanks again for SQX !

I'm having a real good time using it 🙂

Share this post


Link to post
Share on other sites
14 hours ago, Rosetux said:

Hey @engima,
I'm working on a project using SQX and I was wondering if there's a way to initialize public static properties.
I'd like to use a public static property as a class constant, the issue is that there is no way to initialize property at class scope.

...

Thanks again for SQX !
I'm having a real good time using it 🙂

 

Hi. I'm really glad to hear that you like it!

 

To initialize a static property I would create a static initializer - a static "Init" method. And then I would call the Init when the mission starts.

public class EndMissionEventHandler
{
  public static method Init()
  {
    EndMissionEventHandler.EVENT_NAME = "END_MISSION";
  };
 
  public static property String EVENT_NAME { get; private set; };
};

 

And in init.sqx (or similar):

  call compile preprocessFileLineNumbers "EndMissionEventHandler.sqx";
  call EndMissionEventHandler.Init;

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×