AGS 4.0 - Early Alpha 9 for public test

Started by Crimson Wizard, Thu 01/06/2023 14:00:59

Previous topic - Next topic

Crimson Wizard

AGS 4 - Early Alpha 9
Full release number: 4.0.0.4

ACHTUNG!

This is a EARLY ALPHA version of AGS 4.
This is a WIP version, and must go through extensive testing.
Use at your own risk. Please back up any games before opening them in this version of AGS.
New settings in this version WILL make your project files unusable in previous versions after saving with this version.


For Engine/Editor developers
Spoiler


Last updated: 15th March 2024



This release is brought to you by:

- Alan v.Drake
- Crimson Wizard
- eri0o (joystick & gamepad support, other improvements)
- fernewelten (new script compiler)
- ChamberOfFear, aka persn (open room format, Editor improvements)
- Matteo Piovanelli (some improvements)



What is AGS 4

AGS 4.0 is an upcoming version which is currently in experimental stage. The primary idea of this version is a complete removal of the deprecated functionality: game settings and script functions. AGS 4 will no longer be able to run older 2.* or 3.* games. It will only guarantee the import of the latest 3.* game projects (such as 3.6.0). This means that if you want to update your existing game to AGS 4, then you'll have to first import and save it in 3.6.0. If your game is using any of the deprecated settings or script commands - you'll have to replace these, as 4.0 will no longer have necessary "backwards compatibility" switches in General Settings.

It is still in works, and there is a number of large changes planned.
But what are the ready major new features of AGS 4?

Open Room format

The new room format made by @ChamberOfFear now stores rooms as a collection of directories with room data split into multiple files. The room properties are stored in XML, which make it possible to read and even edit by hand outside of the editor. Room backgrounds and region masks are stored as separate PNG images.

This improves the safety of working with rooms, allows to change things externally, and simplify teamwork to some degree.

New script compiler with new syntax features

The new compiler was written by @fernewelten, and it grants a whole bunch of syntax improvements to the AGS script, such as nested structs, multi-dimensional arrays, dynamic arrays have `Length` pseudo-property, and so on.

The full cheat-sheet of the new features may be found here:
https://github.com/adventuregamestudio/ags/wiki/New-compiler%27s-end-user-cheat-sheet
If anyone is curious, here's the more "technical" version, explaining things in depth:
https://github.com/adventuregamestudio/ags/wiki/Features-of-the-new-Script-Compiler

Managed pointers inside managed structs

These are also allowed now (this is not related directly to the script compiler, but also to how engine handles dynamically created objects). This feature finally opens full potential of structs referencing each other with pointers, and allow you to create virtually any kind of data storage in script.

To give an example:
Code: ags
managed struct Item; // pre-declaration

managed struct Person {
    Item* items[];
};

managed struct Item {
    Person* owner;
};

Here's a LinkedList module I wrote for a test:
https://www.dropbox.com/s/sxur2bsccsvaqmr/ags399-LinkedList.zip?dl=0

Advanced object features

The game objects have two new features worth mentioning up front: Blend Mode and Rotation.
* BlendMode property lets you change the way object is drawn, selecting one of the 10 classic modes (Add, Subtract, Dodge, etc). This gives you ability to make more visual effects in your game.
* Rotation property (called GraphicRotation in some) lets you to rotate the object by a number of degrees. Most standard things have this, and even Cameras, so you may, for example, rotate the whole room view, and characters in it individually. Rotation is hardware accelerated (in Direct3D/OpenGL mode) and does not slow things down, unlike rotating dynamic sprites. Engine correctly detects clicks on rotated objects, so for example, rotated GUI will be fully functional.

What else is PLANNED for AGS 4?

Here's the milestone proposal:
https://github.com/adventuregamestudio/ags/issues/1298

It's not clear at the moment whether all of these features will be a part of the first 4.0 release, but at least some of these will hopefully be.

How safe is this WIP version currently?

It is relatively stable, and there are few people who were already using it to make games for a while: Alan Drake is one of them, and I suspect that fernewelten was also using it sometimes for his games because of his new compiler (but I may be mistaken).
The biggest problem with this is that this version will be updated further, so some things may not be final. Project format may also change in the next updates. We'll try to keep things upgradeable (so that the previous projects made in this WIP version won't just break).
And it surely it will benefit from more testers.



The full changelog follows:

Contains all improvements and fixes from AGS 3.6.1 RC5, except ones made for backwards compatibility.

Common:
- Most of the deprecated functionality (game settings and script API) is cut out from both Editor and Engine, and is no longer supported. The Editor guarantees to import the projects saved by AGS 3.6.0 and later. The Engine may run games compiled in 3.6.0, but only so long as they don't use any deprecated settings or script commands.
- Completely removed Global Messages and Room Messages.
- Removed built-in support for Game Score, including related game settings and GiveScore script command. Users are advised to script their own score counter if they need one.
- Removed support for '[' as a linebreak character in text.

Editor:
- Open room project format: rooms are now saved as subfolders in "Rooms" folder, where each component has its own separate file (room data, backgrounds, masks and scripts).
- Support room backgrounds and masks as PNGs.
- Translation sources are now saved in PO format.
- General panel look enhancements.
- Support built-in Base Color Themes that have the custom themes applied over them.
- Game template selection now displays template's description right in the dialog.
- F2 is now a hotkey for editing labels in the Project Tree. "Game statistics" are now displayed by Ctrl + F2.
- Script editor supports "word wrap" mode.
- In General Settings added "Use extended compiler" option that lets to choose a new script compiler for your game (see list of changes in related section below).
- Added Enabled and Visible properties to Characters, Enabled property to Room Objects.
- Added BlendMode property to Characters, GUI and Room Objects.
- Added FaceDirectionRatio property to General Settings, Room and Walkable Areas.
- Added readonly Length property to AudioClips, for the reference.
- Fixed 8-bit images imported and converted for a 32-bit game to not get their colors clamped to a low-precision palette.
- Fixed faulty double-click on project items in case user dragged the cursor away.

Compiler:
- The new extended script compiler is available. Almost all of the new Scripting features are only supported when using the new script compiler.
- Optimization to the bytecode generation: same scripts may now work faster at runtime.

Scripting:
- Support for having regular structs inside any structs (regular or managed); there's no nesting limit.
- Support having managed pointers inside managed structs.
- When declaring a pointer to managed struct you may now omit "*" sign.
- When writing struct's function's code you may now omit "this" keyword when addressing current struct's member (variable, attribute or function).
- Extender attributes; similar to extender functions, but these define a pair of get_ and set_ functions.
- Multi-dimensional regular arrays. They may have any positive number of dimensions.
- Multi-dimensional dynamic arrays, also known as "jagged arrays". These are arrays of arrays, where each parent array's element has to be created separately, but may be of any independent length.
- Regular arrays of dynamic arrays: that is a regular array where each element is a pointer to a dynamic array of the same type.
- Dynamic arrays of regular structs.
- Dynamic arrays now have Length pseudo-attribute used to retrieve their length.
- Global variables may now be declared right after struct's or enum's declaration, between the closing bracket and closing semi-colon.
- Functions now may call any other function from within same script, regardless of their order of declaration.
- Compiler can now evaluate integer or float expressions at compile time whenever result is actually constant and can be calculated at compile time.
- "const" keyword now may be used to define compile-time "int" and "float" constants.
- "readonly" keyword now may be used to declare non-modifiable variables (local or global) and function parameters.
- Added "fallthrough" keyword, which is used to hint that switch's case does not require a break statement. This is only to clarify coder's intent and prevent compiler's warnings.
- Support pre-increment and pre-decrement operators (++x, --x).
- Support bitwise negation operator (~x).
- Support addressing members of the function return values in one expression. This lets chain multiple commands including function calls, e.g. GetObject().MyVariable...and so on.
- Two sequenced string literals ("text" "text") are now automatically concatenated.

Script API:
- Most of the deprecated API is now removed completely, except those that have no equivalent.
- Added SCRIPT_EXT_AGS4 macro which tells whether extended script syntax is supported by the compiler. This may be used to know whether the script is being compiled by the old or new compiler.
- Added SCRIPT_EXT_NESTEDPOINTERS macro which tells whether nested managed structs are supported by the compiler.
- Added Joystick struct, meant to work with joystics and gamepads in script.
- Added VideoPlayer struct, which provides means of playing non-blocking videos rendered onto a sprite that may be displayed on any game object.
- Added WalkableArea and Walkbehind structs which let work with these region types in OO-style.
- Added BlendMode enum.
- Added Character.Enabled and Visible properties, added Object.Enabled property, Character.on is deprecated.
- Added Character.BlendMode, GUI.BlendMode, Object.BlendMode, Overlay.BlendMode.
- Added Character.UseRegionTint and Object.UseRegionTint, deprecated Character.IgnoreLighting.
- Added Camera.Rotation, Character.GraphicRotation, GUI.Rotation, Object.GraphicRotation, Overlay.Rotation.
- Added Game.FaceDirectionRatio, Room.FaceDirectionRatio, WalkableArea.FaceDirectionRatio and Character.FaceDirectionRatio.
- Added DrawingSurface.BlendImage() and DrawingSurface.BlendSurface() functions.
- Added File.Rename().
- ListBox.FillSaveGameList(), RestoreGameDialog() and SaveGameDialog() now let define a range of save slots for display.
- Added MoveSaveSlot() which renames a savegame.
- Added "walkarea[]" and "walkbehind[]" global arrays.
- Global arrays of game objects (Characters, GUIs, etc) are now declared as arrays of object *pointers*. From the user's perspective this is a mere formality, as working with these arrays will be syntactically same, but this makes it easier for the engine to handle these arrays and objects internally.
- Removed "hasAlphaChannel" param from DynamicSprite.Create() and CreateFromExistingSprite().
- Removed HasAlphaChannel property from DialogOptionsRenderingInfo.
- Removed "transparent" param from Overlay.CreateGraphical() and CreateRoomGraphical().
- Removed Object.MergeIntoBackground() function as redundant, and complicating Object's logic.

Engine:
- Support joystick and gamepad input.
- Implemented more accurate Character movement. The movement direction is now more precise and diagonal movement speed no longer may exceed MovementSpeed setting.
- Camera will not follow a disabled player character.
- Animated buttons now display flipped frames correctly.
- AudioChannel.Position and PositionMs no longer return a very large value while skipping cutscene.
- DeleteSaveSlot() no longer causes highest save to be renamed to fill a gap in saves.
- Added FLAC support for music, speech and sound effects.
- Added "--print-rtti" command line option which prints script RTTI table to the log.
  (RTTI stands for "runtime type information", and is used for handling of certain advanced
  script features, such as nested managed structs.)


Crimson Wizard

#1
KNOWN ISSUES

[FIXED]1. Some room backgrounds may become fully transparent after the project import. Their RGB colors persist, but alpha channel becomes 0 in every pixel.
The workaround currently is either to reimport background from the original source, or to open a bg png in the Rooms dir and fill alpha channel with opaqueness (if you graphic editor allows that).



2. There are couple of functions which now have less arguments compared to the previous versions of AGS.

These functions are:
- DynamicSprite.Create and DynamicSprite.CreateFromExisting, they no longer have "has alpha" argument, as in 32-bit games all sprites are considered to have usable alpha channel now. (This is actually under question, and may change again to e.g. have an argument that defines a pixel format)
- Overlay.CreateGraphical does not have "transparent" arg, as it was useless all the way.

This is an unusual case (commonly arguments are added). This may cause script errors if you import a project or a module.

The solution for a quick fix, when you don't want to manually fix all these function calls in your game, is to create a script module on the top of the scripts list, and place helper extenders there which wrap actual function calls, like this:

Code: ags
DynamicSprite* Create(static DynamicSprite, int width, int height, bool unused)
{
    return DynamicSprite.Create(width, height);
}

static DynamicSprite* DynamicSprite.CreateFromExistingSprite(int slot, bool unused)
{
    return DynamicSprite.CreateFromExistingSprite(slot);
}

Overlay* CreateGraphical(static Overlay, int x, int y, int slot, bool unused, bool clone)
{
    return Overlay.CreateGraphical(x, y, slot, clone);
}

Overlay* CreateRoomGraphical(static Overlay, int x, int y, int slot, bool unused, bool clone)
{
    return Overlay.CreateRoomGraphical(x, y, slot, clone);
}

Eon_Star

Hi,

I tested this version. When in room editing window the background PNG was not visible (Gray Background). In the game window however it was ok. Thanks for your efforts.

eri0o


Crimson Wizard

Quote from: Eon_Star on Fri 02/06/2023 22:12:38I tested this version. When in room editing window the background PNG was not visible (Gray Background). In the game window however it was ok. Thanks for your efforts.

Hello, this is a known issue that I'm currently looking at. The background does not actually become grey, it becomes fully transparent with alpha channel = 0. It's visible in the game because the engine forces room bgs to be rendered opaque.

The workaround currently is either to reimport background from the original source, or to open a bg png in the Rooms dir and fill alpha channel with opaqueness (if you graphic editor allows that).

Eon_Star

Thank you Crimson Wizard. I think this version will be great. :-D


Eon_Star

I did dowload the fixed version. Keep up the good work and stay healthy. ;-D

Crimson Wizard

Updated to Alpha 2
(Please use download links in the first post)

Contains updates and fixes from 3.6.1 Beta 3.

Other changes:

Editor:
- Fixed room backgrounds with color depths < 32-bit (like 24-bit rgb) could display fully transparent in the Editor after project upgrade.
- (possibly) Fixed incorrect "script was modified externally" message occuring when it was not actually modified externally.

Compiler:
- Fixed `++` and `--` operators could be used wrongly as a binary op (like `a ++ b`), and compiler did not detect any error.

Engine:
- Fixed character/object scaling not working at all, because of a typo in code.

Crimson Wizard

Updated to Alpha 3
(Please use download links in the first post)

Contains updates and fixes from 3.6.1 Beta 6.

Other changes:

Common:
- Removed support for '[' as a linebreak character in text.
  Please use a standard '\n' from now on.

Editor:
- Support loading PNGs with transparent chunks as Room Masks.

Engine:
- Fixed flipped button frames displayed without transparent parts.




You might have noticed that there was not much of new additions to AGS 4 updates besides than merging 3.6.1 updates in. There are currently couple of major changes in works:
- Translation migration from classic AGS TRS format to a more widespread PO format, which should make working with translations safer, and make adding further translation features easier.
- Joystick/Gamepad script API.

I believe these two will be introduced in the next AGS 4 Alpha update.

Baguettator

Just a big congrats to all of you who are still working on this incredible free  and rich program !! I will test AGS 4.0 as soon as I can !

I have a question that could be (or not) a suggestion for AGS development : is it possible to create during runtime new buttons or GUICOntrols or things like that ? I mean : the game could manage new buttons that have not been created in the editor, but created during playing the game ?

My idea is that I'm making a "map editor" for something, so I have to place tokens (tiles, events, starting zones, objectives, characters etc...) to create a map. I can't imagine doing this another way than using GUIControls (or characters, or room objects) to represent tokens, to easily be able to manage clicks on them to delete, rotate, move etc...

The problem is that it will necessary limit the possibilities, the number of tokens "available" because I can't have infinite GUIControls. I have to create 100 GUIControls, and I can't add more than 100 tokens for a map (for example).

So, the idea would be to be able to create new Buttons in runtime. Each time I create a token, it creates a Button that could be a copy of another one (for the scripts functions attached to them for example), and then act on them (change the graphic, the orientation etc...).

Is it a limitation of AGS Engine ? Or a limitation of engines in general ? Or something like that could be possible ?

Probably my question is stupid, as I'm not an expert like you. But perhaps... :)

Also, I hope my post is at the right place, as I thought it was a "development consideration", but sorry if it's not the case, I can delete it if necessary.

Anyway, congrats for AGS workers that make it possible to have such a program !

Crimson Wizard

#11
Quote from: Baguettator on Sun 06/08/2023 08:42:21Is it a limitation of AGS Engine ? Or a limitation of engines in general ? Or something like that could be possible ?

This is the current limitation of the AGS engine. But frankly this is more of a design issue rather than a technical one. In other words, it's not too hard to create a button at runtime, it may be complicated to logically bind this with how the engine treats the objects created in the editor.
This is further complicated by AGS not supporting linking functions to events in script, which means that even if you create a button in script, you won't be able to receive click events from it.

Supporting doing this is theoretically in TODO (for a long time).

Quote from: Baguettator on Sun 06/08/2023 08:42:21My idea is that I'm making a "map editor" for something, so I have to place tokens (tiles, events, starting zones, objectives, characters etc...) to create a map. I can't imagine doing this another way than using GUIControls

For the purpose of having unknown number of objects on screen there are 3 existing options:
1. DrawingSurface. This is a traditional method. You may drawing anything, but you will have to store all the object properties in your custom structs, including their positions.
2. Overlays. They are not limited anymore since 3.6.0. The benefit of these for the map editor is probably that you don't have to script redrawing a map when moving/deleting these, and they may use fast scaling & rotation (may be not exactly important for the map editor).
3. Using a pool of objects. Will limit number of simultaneous objects on screen, so probably not the best solution for the map editor.

With the first two options you have to detect clicks yourself. How this is done depends on your use of them. If this is a "tiled" map editor that might be rather simple, since you can calculate which tile the player clicked on and proceed from that. Overall this is a big technical topic, which I won't like to cover in this forum thread.

Snarky

#12
@Baguettator, you may want to check out the ImGi module, which allows you to create GUI Controls in script (though they're not "real" Controls, but a reimplementation using Overlays). Though since what you're trying to do isn't actually to create a GUI, you may be better off just implementing what you're trying to do yourself, as CW explains.

eri0o

Hey, my ImGi module started as using Overlays but it quickly changed to be based to Drawing Surface with it's own hashed-dirty-rects system due to the limitations of Overlays at the time - like, there was no sorting of overlays at the time.

There is still one limitation that makes it rather tricky to rewrite it as hardware accelerated that is there is no clipping in an Overlay, and this makes something like scrolling a bit hard to do - like, I would need to make things hardware accelerated and selectively degenerate things as software drawn when they were clipped, which is a bit hard. If there was some hardware accelerated clipping, than it could be done easier. Alternatively, some sort of Camera system in the GUI space would also work - although much harder to manage from a scripting perspective, "clippable " overlays would be far easier.

Baguettator

Thanks for answers ! I didn't expect that it was a limitation of AGS engine, but something not too hard to update. So good news ! Even if it will take time to be achieved, I think the best thing is to wait and sometimes push the idea to ags developers :D

Thanks for the solutions and for erioo's module, it's what I thought about (I've never worked with overlays, but sounds great !). For now I'll stay with Guicontrols, as I have already implemented many things with it and it's easier to script. When Ags will be ready... I'll change :)

So, good news ! I hope to test AGS 4.0 soon !

Baguettator

EDIT : Crimson Wizard, you told that it's not complicated to create a button at runtime ? The biggest problem to link it to functions in script ? But does that mean that we could have AGS able to create buttons at runtime, and then we could interact with buttons using the "mouse_onclick" function, something like :

Code: ags
function onmouse_click ()
{
  GUIControl *g=GUIControl.GetAtScreen(mouse.x, mouse.y);
  if (g.Graphic==12)
  {
    //I know which token it is, so I do that
  }
}

It could be as simple as it, waiting for a long time if one day it could be possible to do more complex thing, attaching functions dynamically to controls by script. But if that simple case could be possible... could be great, isn't it ? :)

Crimson Wizard

#16
Quote from: Baguettator on Sun 06/08/2023 22:26:38EDIT : Crimson Wizard, you told that it's not complicated to create a button at runtime ? The biggest problem to link it to functions in script ?

That is not the first problem. There's a number of things that have to be decided and changed in the engine to make supporting this convenient. I would have to go into more detail to explain, but I do not want to do this in this forum thread.

But, besides, if the button is not bound to events, then what's the point of creating it? It's easier to create an overlay.
Overlays are simpliest graphical objects in AGS, they are fast, flexible, may exist both on GUI and Room layer, and already support more graphic effects than buttons (e.g. scaling in 3.6.0 and rotation and blend in ags 4). This actually makes them superior to buttons, at least at the moment, if you excuse the lack of an automatic reaction to clicking.

You may do almost same thing in on_mouse_click with overlays as you do with buttons, except you need to write your own GetAtScreen for them.

Baguettator

Yeah, but scripting an overlay to detect mouse clicks would be harder, isn't it ? I thought having a button is easier to detect that it's a button and I click on that, even if it doesn't have any function linked to it.

Crimson Wizard

#18
Quote from: Baguettator on Sun 06/08/2023 22:54:52Yeah, but scripting an overlay to detect mouse clicks would be harder, isn't it ?

Supposedly, but that's a typical problem, and has its solutions for a script.

EDIT:
It's also possible to add GetAtScreenXY for overlays too, I did not add that at a time because I wanted to keep its API simple, but guess it was a wrong idea.
The problem this is coupled with is that currently GetAtScreenXY works simply by iterating over all objects of the type and testing the coordinates. This will become slow with the large number of objects created, so some kind of an optimized algorithm would be prefered, like space partitioning. But same goes to anything else that would support dynamic creation.

vga256

I am beginning AGS4 testing on a game that requires the new features offered by the new data structures. Please let me know if there are specific features or functions the team would like to see tested as I work.

Although I know this is not the proper place for this - I am also among those who needs support for runtime-generated/dynamic GUIs. Scripting workarounds to emulate this (e.g. spawning dozens of empty GUI elements and then showing/hiding them at runtime) is currently extremely painful as a developer.

For the time being, GetAtScreenXY for Overlays alone would be hugely useful for projects like mine.

SMF spam blocked by CleanTalk