AGS 3.6.0 WIP (Alpha 21) - SDL2-based engine + Unicode support

Started by Crimson Wizard, Thu 25/03/2021 02:28:54

Previous topic - Next topic

Laura Hunt

I'm not sure this is the best place to leave a suggestion, but right now, the only way to change the delay of a view frame is manually in the View editor, and it can get quite cumbersome if for whatever reason you need to change the values for a lot of frames. How feasible would it be to expose the view frame delay property to the script?

Crimson Wizard

Quote from: Laura Hunt on Thu 14/10/2021 18:54:15
I'm not sure this is the best place to leave a suggestion, but right now, the only way to change the delay of a view frame is manually in the View editor, and it can get quite cumbersome if for whatever reason you need to change the values for a lot of frames. How feasible would it be to expose the view frame delay property to the script?

Delay is already exposed to script, but as a readonly property called "Speed". Making it writeable is mostly a matter of adding this field to savegames, otherwise saving/restoring game will make frame data inconsistent.

But I guess this is also why the view editor needs multiple selection and being able to edit properties from multiple frames at once.

Laura Hunt

Quote from: Crimson Wizard on Thu 14/10/2021 21:37:19
But I guess this is also why the view editor needs multiple selection and being able to edit properties from multiple frames at once.

Agree, that would also be a very welcome addition. But I guess it would take more work?

Crimson Wizard

Quote from: Laura Hunt on Thu 14/10/2021 21:55:55
Quote from: Crimson Wizard on Thu 14/10/2021 21:37:19
But I guess this is also why the view editor needs multiple selection and being able to edit properties from multiple frames at once.

Agree, that would also be a very welcome addition. But I guess it would take more work?

Editor currently does not have any mechanism for this, there might be a default handling available for the PropertyGrid control, but I know nothing about that.
Someone has to research how this works first.

Crimson Wizard

Unfortunately I got very distracted from AGS recently, so this took more time since the last update... but here's the new one.

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

Editor:

* Added "Use graphical font height in game logic" property to the General Settings, that makes your game use real font's pixel height when arranging text and text-based UI elements, as opposed to the nominal font's size. This is important for TTF fonts, because importing them with N point size does not guarantee N pixel height. Unfortunately AGS used to "lie" about their height all those years, which could lead to some fonts not fitting into gui controls right or even have their bottom parts "cut off" when displayed as a speech. Now you may prevent that using this setting.
* Fixed "Use old-style custom dialog options API" was not set when importing pre-3.4.0 projects.
* Fixed comboboxes' drop-down arrows were not painted with the right color from a color theme.

Script compiler:

* Removed 500-characters line limit.

Script API:

* Debug(2, 0) command that displayed walkable areas is superceded by Debug(2, n), where "n" is a mask type: 0 - none, 1 - hotspots, 2 - walkbehinds, 3 - walkable areas, 4 - regions. This command also works as a toggle switch, calling it with the same mask index will turn it off.
* Debug(5, n) command that displayed character's walk paths now also works as a toggle switch.

Engine:

* Support "borderless full-screen window" mode in addition to the real (exclusive) fullscreen.
* Support scripts using functions and variables (imported) from any other scripts, regardless of the script module order in the project. These still have to be declared as "import" above their use though.
* Engine now supports using real pixel height of the TTF fonts when arranging text and UI elements on screen; using nominal import size of the font is used as a compatible mode for the old games.
Note that you may always configure the vertical line spacing using font's LineSpacing property in the editor.
* Engine now ensures that in threaded audio mode the script's AudioChannel's state only changes once the game is updated, and not while the game script is running. This prevents situations when the clip could begin playing before all properties are set in script, or when AudioChannel's properties' values (such as Position) could change while running a game script.
* Character.SetWalkSpeed() is no longer restricted by an arbitrary limit of 50.
* File.ReadRawLineBack() now always reads full line, and not limited to 200 characters anymore.
* Debug displays, such as showing room mask and character walk paths, are now implemented as non-blocking translucent overlays, allowing you to keep playing the game while they are on.
* Engine config now has graphic modes defined as a simplier string options: "[graphics] fullscreen" for the fullscreen mode setup, and "[graphics] window" for the windowed. Fullscreen option can explicitly define a "borderless full-screen window" mode. (See below for the new config explanation; it will be also added to documentation later).
* Fixed engine could crash due to incorrect disposal of resources if its startup was interrupted for any reason.
* Fixed some TTF fonts were not centered correctly and/or cut from below when text is displayed.
* Fixed crash in case there were too many reserved audio channels.
* Fixed new sound panning implementation.
* Fixed character may have incorrect Frame values while turning.

Android:

* Fixed reading of separate game files (not merged with the main AGS game file) from inside the APK.

WinSetup:

* Added "Fullscreen as borderless window" checkbox.




New graphics mode configuration:

Instead of having several detached options that combined would result in a window size definition, there's now only 1 option (per mode) that contains all possible variants in a single string:
* WxH - explicit window size (e.g. 1280x720);
* xS - integer game scaling factor (e.g. x4);
* desktop - use current system's desktop resolution;
** in windowed mode will try to create largest possible resizing window, while keeping game scaling style (max stretch, proportional stretch or max integer multiplier);
* native - use game's native resolution;
* full_window - special option for the fullscreen mode, this means a borderless window covering whole desktop;
* default - currently we default to (this is also a fallback option in case config parsing went wrong):
** in fullscreen mode to full_window;
** in windowed mode to desktop;

In [graphics] section fullscreen mode is defined by the option "fullscreen" while the windowed mode is defined by the option "window".

Config examples:

Code: ags

[graphics]
fullscreen=1280x720
window=x2
game_scale_fs=proportional
game_scale_win=round


Code: ags

[graphics]
fullscreen=full_window
window=native
game_scale_fs=stretch
game_scale_win=round

Dave Gilbert

Hooray! Thanks CW.

I am not sure if this is a bug or not, or if it's specifically related to version 3.6, but I noticed a weird issue when switching between monitors.

I have a two monitor setup. One laptop and a second monitor. I typically have the monitors in "Extend" mode (where the desktop area is spread out between the two) and test my game on my second monitor. If the game is running and I switch from "Extend" mode to "second screen only" mode, the game minimizes itself and won't come back. Clicking on the icon in the taskbar does nothing (although I can still hear the music and sound). I have to open up the task manager to exit out of the game.

I admit this is an unusual case that not many people will deal with, but it is a bit annoying when it comes up.

Anyway, I'm off to play with fonts now!

-Dave

greg

Thanks for this awesome new build!  The Object.Scaling option and additional audio channels are especially amazing.

When testing out the most recent version of 3.6, I noticed the following:

1. Text within buttons is placed differently in the editor than in the game.  Here’s some text with alignment eAlignMiddleCenter.  (The font is LinLibertine_aBS.ttf, imported at 20 pt.)

https://drive.google.com/file/d/1VYqbj3KUjmCIAcXKTJudgZ33z8IkCJMw/view

It’s worth noting that, when upgrading from 3.5.1 to 3.6, the font had a VerticalOffset of -2, which appeared as -2 in the editor and -4 in the game.  I’ve since set this offset to 0, and it now appears as 0 in the editor and -2 in the game.

2. Calling GetGlobalInt before SetGlobalInt results in a crash.  As my game was loading, I was calling GetGlobalInt(foo) before I’d called SetGlobalInt(foo, bar).  In 3.5.1, there was no error or crash.  In 3.6, there was a crash.  I addressed this by updating my script to set the variable before getting it.  I wanted to report it, though, as it’s a different behavior from 3.5.1.

Crimson Wizard

Quote from: greg on Fri 05/11/2021 12:40:59
1. Text within buttons is placed differently in the editor than in the game.  Here’s some text with alignment eAlignMiddleCenter.  (The font is LinLibertine_aBS.ttf, imported at 20 pt.)

I am currently experimenting with changing something in how TTF fonts work, and latest build unfortunately may contain mistakes. I realized this too late, when it was already posted. In any case it's better to not rely on the font looks right away and wait until the next update, which hopefully will be ready soon enough.

Quote
the font had a VerticalOffset of -2, which appeared as -2 in the editor and -4 in the game

This sounds weird though. But I will look at this as soon as I fix other obvious mistakes.

Quote from: greg on Fri 05/11/2021 12:40:59
2. Calling GetGlobalInt before SetGlobalInt results in a crash.  As my game was loading, I was calling GetGlobalInt(foo) before I’d called SetGlobalInt(foo, bar).  In 3.5.1, there was no error or crash.  In 3.6, there was a crash.  I addressed this by updating my script to set the variable before getting it.  I wanted to report it, though, as it’s a different behavior from 3.5.1.

I will look into this, but just wanted to mention that these functions were deprecated many years ago, today it's recommended to use normal variables in script.

Matti


Crimson Wizard

@greg
Quote from: greg on Fri 05/11/2021 12:40:59
2. Calling GetGlobalInt before SetGlobalInt results in a crash.  As my game was loading, I was calling GetGlobalInt(foo) before I’d called SetGlobalInt(foo, bar).  In 3.5.1, there was no error or crash.  In 3.6, there was a crash.  I addressed this by updating my script to set the variable before getting it.  I wanted to report it, though, as it’s a different behavior from 3.5.1.

I tried this, and I cannot reproduce a crash, nor see how exactly it may happen.

Could you give more information, like post the exact script, tell what function do you call the GetGlobalInt from, what kind of crash (were there error messages)?

greg

Sure, I've appended the crash message below, and I've uploaded the CrashInfo file here: https://drive.google.com/file/d/1WNVKOHaYn9HYax55KrQxvRI79nyY3A82/view?usp=sharing

The functions that called GetGlobalInt(foo) before SetGlobalInt(foo, bar) were called in game_start().  Also, thanks for the heads-up that GetGlobalInt and SetGlobalInt have been deprecated!

Separately, since upgrading from 3.5.1 to 3.6, I noticed that AudioChannel.LengthMs is sometimes returning 0 even when AudioChannel.PlayingClip.ID is not null.  Namely, in the same place in my code, the same log message sometimes prints this:

Code: ags
channel.ID: 3, channel.PlayingClip.ID: 267, channel.LengthMs: 3692


And sometimes it prints this:

Code: ags
channel.ID: 3, channel.PlayingClip.ID: 267, channel.LengthMs: 0


I can reproduce this consistently, but not every time, when I skip the cutscene in which the clip is played.  However, the behavior sometimes occurs (though far less often) even if I don’t skip the cutscene.  (I had the same code in AGS 3.5.1, and channel.LengthMs never returned 0.)

---------------------------
Illegal exception
---------------------------
An exception 0xC0000005 occurred in ACWIN.EXE at EIP = 0x00537F70; program pointer is -42, ACI version 3.6.0.10, gtags (78,214)

AGS cannot continue, this exception was fatal. Please note down the numbers above, remember what you were doing at the time and contact the game author for support or post these details on the AGS Technical Forum.

in "Interface.asc", line 1001
from "Interface.asc", line 1010
from "Extender.asc", line 587
from "Extender.asc", line 596
from "Extender.asc", line 1090
from "Extender.asc", line 3539
(and more...)

Crimson Wizard

Quote from: greg on Sat 06/11/2021 16:55:26
Sure, I've appended the crash message below, and I've uploaded the CrashInfo file here: https://drive.google.com/file/d/1WNVKOHaYn9HYax55KrQxvRI79nyY3A82/view?usp=sharing

The functions that called GetGlobalInt(foo) before SetGlobalInt(foo, bar) were called in game_start().

From thois crash dump it seems that the last called function was GetWalkableAreaAtRoom. But maybe there was something wrong with either engine or the dump.

Could you post the code around "Interface.asc", line 1001 ?

EDIT: I can confirm that calling GetWalkableAreaAtRoom in game_start will crash the engine. No room is loaded at the time when game_start was called, but it seems this time engine was not able to handle that properly and display a regular error.

greg

Sure, here's the code.  Line 1001 is the one with "GetWalkableAreaAtRoom(player.x, player.y) != GetGlobalInt(EXIT_WA_ENABLED)":

Code: ags
function exit_hidewalkablearea() {
  if (GetGlobalInt(EXIT_WA_ENABLED) != -1) {  // line 999
    // don't hide walkable area if the character is currently on top of it
    if (GetWalkableAreaAtRoom(player.x, player.y) != GetGlobalInt(EXIT_WA_ENABLED)) {  // line 1001
      RemoveWalkableArea(GetGlobalInt(EXIT_WA_ENABLED));
      SetGlobalInt(EXIT_WA_ENABLED, -1);
    }
  }
}


In 3.6 (but not in 3.5.1), when I call this function before setting SetGlobalInt(EXIT_WA_ENABLED, -1), I get the crash from the dump file.  Now that I'm setting the variable first, I no longer get the crash (because it fails the condition at line 999).

I'd guess the change in behavior here is that 3.5.1 returns -1 for GetGlobalInt(foo) if foo hasn't been set, whereas 3.6 doesn't?  So in 3.5.1, even though I hadn't set the variable, it failed the condition at line 999 and never tried calling GetWalkableAreaAtRoom().

Thanks,
Greg

Crimson Wizard

Quote from: greg on Sat 06/11/2021 23:31:45
I'd guess the change in behavior here is that 3.5.1 returns -1 for GetGlobalInt(foo) if foo hasn't been set, whereas 3.6 doesn't?  So in 3.5.1, even though I hadn't set the variable, it failed the condition at line 999 and never tried calling GetWalkableAreaAtRoom().

I never paid attention to this, but just tested in several versions including 3.5.1, and it always returns "0" if called before SetGlobalInt.

Although looking at the engine code, it seems like this global ints array is not properly initialized in program memory at the game start, which in theory means that these values could be anything and must not be relied upon. So, I'm not really sure how they may have any consistent values as shown by tests.

Crimson Wizard

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

IMPORTANT: I remade one recently added property in General Settings, and unfortunately this conflicts with the previous build (Alpha 11). If you already used that build, here's what you need to do to make your project open in the current version again:
- Open Game.agf in a notepad;
- Search for the line starting as "<UseRealFontHeight>" and delete it. Save the file.

I apologize for this inconvenience.


TTF fonts setup

In this version I implemented a way to configure how TTF fonts are loaded and displayed in AGS. The problem was that AGS historically did some fixups to TTF looks for backward compatibility, but that made some fonts act worse and not position correctly when drawn in game. There are two new properties in the project that let to specify either new and old behavior.

1) "TTF font adjustment" - this property exists in Fonts and may be set individually for each of them; also similar property is in General Settings and sets default value for each new font you add to your game. This property lets you choose between "no changes" and backward compatible TTF fixup called "Resize ascender to the nominal font height".

To clarify a little, what this "fixup" means: the font has ascender and descender parts separated by a baseline. Ascender is parts of letters above baseline, descender is parts below baseline.
In the past AGS forcefully resized ascender to match the font's size. This could lead to ascender becoming larger or smaller. Because AGS draws texts starting with top-left corner, such change would result in text appearing shifted up or down relative to what you'd normally expect.
Now you may disable this behavior. The ability to keep it for the chosen fonts is left because there's a number of TTF fonts around created specially for AGS, possibly taking this weird behavior into account. For these fonts it may be desired to retain this "fixup".

2) "TTF fonts height used in the game logic" - this property exists in "General Settings" and has a global effect on all fonts. It lets you select what value is used as a height of line of text in game: TTF's nominal size (in "points") or real size in pixels. "Nominal size" is a backward compatible choice.

Why there's a difference: TTF are vector fonts, which do not always scale 1:1 to pixels because they must keep letter proportions. So, when you tell AGS to import a font at size 10, the actual pixel size may end up equal to 10, bit less or larger. Historically AGS ignored that fact and always reported text height using the "nominal" size, but that was a "lie".
The best way to check this out is to put some common TTF font on a GUI, and set GUI's height exactly to the font's size. In many fonts you will notice that some letters (usually "q,j,g,y" and similar) will not fit in, sometimes by a noteable amount.

So, now there's a setting that lets you enable using real height. This means that if you do GetTextHeight or GetFontHeight and so on -- it will report correct pixel heights of a text. Also, default font's linespacing is set equal either to the nominal or real height depending on this setting. But linespacing may also always be customized using corresponding Font's property, in the editor ("LineSpacing").


Other changes:

Editor:
- Fonts now have a readonly Family Name field, that lets user see the original name of a font they've imported (if available).

Engine:
- Fixed potential crashes if a room-related API function has been called in "game_start"; this is achieved by having a dummy room placeholder object. Still results of such calls are undefined and should not be relied upon.
- Fixed some TTF fonts could be cut at the bottom when the speech is displayed.

Compatibility
- When running pre-3.4.1 games, anti-aliased TTF fonts display is now corrected (their vertical position was broken).

greg

Thanks very much, CW!  This fixed both the font issue and the hard crash in game_start() I'd been encountering.

Of the issues I'd reported, I'm only still experiencing the flakey AudioChannel.LengthMs issue.  That is, AudioChannel.LengthMs is sometimes returning 0 even when AudioChannel.PlayingClip.ID is not null.  (Details are a few appends down, but if you need further debugging information from me, just let me know.)  Thanks!

Baguettator

Great news about this new version !

I hope it will be soon a first 3.6 beta release :)

Good job, keep going ! ;)

Crimson Wizard

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


PLEASE NOTE: For the technical reasons Editor now requires .NET Framework 4.6 to run (was 4.5).


Multiple Speech VOX support

Editor now packs alternate speech voxes, by scanning the top-level directories inside the "Speech" folder. For each top-level subdirectory It creates a sp_[name].vox where [name] is the lowercase subdir name.

For example, if you have this in your game project:

- Speech
- - Francais
- - MyLang

The editor will create following voxes:

- speech.vox (with top-level files from the root "Speech" folder);
- sp_francais.vox (with top-level files from "Speech/Francais");
- sp_mylang.vox (with top-level files from "Speech/MyLang");


Engine supports switching to a different speech vox anytime. To order so, there's a new script function Game.ChangeSpeechVox(string name), where you pass the "[name]" part of the vox filename. E.g. if you have sp_francais.vox then do Game.ChangeSpeechVox("francais"). For default speech.vox pass empty string. The new readonly property Game.SpeechVoxFilename returns current vox name. This works in similar fashion to the functions that control translations.

Note that speech vox selection is not tied to the current text translation in any way, so you may switch both text and voice to the same language, or switch them to different languages to have e.g. French voice-over with English text.



Other changes:

Editor:
- In the "Import TTF" dialog added a choice to import the size closest to the given pixel height (because TTF's point size does not 1:1 correspond to the size in pixels).
- Default config is now saved also when the game is run in debug mode (F5). This ensures that the test run is using the latest Default Setup, if the user's config has not been created yet.
- Editor no longer errors on empty translations when compiling the game.
- Editor now exports values of the string type Custom Properties to translations.

Engine:
- Engine no longer bails out with error if the chosen translation cannot be loaded on startup.
- Fixed previous music was not gradually lowering volume when crossfading (regression in 3.6.0).
- Fixed game window becoming non-resizing after switching from fullscreen (regression in 3.6.0).

nightmarer

Hello all.

Any update about the PNG compression for this new version?

Regards.

nightmarer

BTW I see at the beginning of my game that the black background, which it was blac at 3.5.1 now is pink.
After that everything is fine.
Any reason for that?

SMF spam blocked by CleanTalk