AGS 3.4.1 - Patch 3

Started by Crimson Wizard, Wed 11/07/2018 00:16:02

Previous topic - Next topic

Crimson Wizard

AGS 3.4.1 - Patch 3 released
Current release number: 3.4.1.14



For Android
Spoiler

For developers
Spoiler


Released: 11th July 2018

Previous stable version: AGS 3.4.0 forum thread


PLEASE TAKE A NOTE: In this version "Default" template is now named "Sierra-style".
(Need to make this warning, because several people have asked where did "Default" template go.)


This release is brought to you by:

- Alan v. Drake
- ChamberOfFear
- Crimson Wizard
- Gurok
- monkey0506
- Ryan O'Connor (one bug fix contribution)
- Scorpiorus (improvements to plugin drawing system)

And artists of the new Sierra-style template:
- CaesarCub
- Hobo
- Jim Reed
- ProgZmax
- Selmiak


Changes in the Patch 3:

Editor:
- Added scrollbars and zoom slider to the GUI editor.
- Added one extra zoom step to the Room editor and fixed mouse wheel scrolling zoom slider by 3 steps at once instead of 1.
- Fixed Undo history getting lost after saving the script.
- Fixed crash when importing old game's rooms with interaction variables.
- Fixed incorrect character names appearing after old game's import.

Engine:
- Reverted conversion of all graphics on load to 32-bit, made the game run in its native color again, but correctly convert to 32-bit display instead. This fixes certain bugs found in 16-bit games since the first 3.4.1 release.
- Fixed pressing ALT+ combination on Windows sometimes caused another key to "stuck", endlessly triggering key events in game.
- Fixed service key shortcuts (switching display mode, (un)locking mouse in window) did not work at particular stages of the game, like video playback and dialog options.
- Fixed unwanted transparency on built-in GUI in 8-bit games.
- Fixed engine was reporting string format errors as internal ones and not script's.
- Fixed crash when loading an old game's room with interaction variables.


Changes in the Patch 2:

Templates:
1. Now includes new "Sierra-style" template which substitutes elderly "Default" template and contains new age graphics.
Template topic: http://www.adventuregamestudio.co.uk/forums/index.php?topic=54703.0
2. Made small fixes to the Verb Coin template to make it compatible with 3.4.1 out of the box.

Editor:
- Font's line spacing and offset are now used when displaying GUI previews.

Engine:
- Removed limit on maximal asset files in a game package. (Now you may have over 10k voice files in speech.vox)
- Fixed game refused to start at all if speech.vox has bad format.
- Fixed DynamicSprite.SaveToFile() was not appending default  "bmp" extension if user did not specify one.

Android:
- Updated port to work with 3.4.1 engine. Software renderer works again too (was broken in 3.4.0).



Changes in the Patch 1:

Engine:
- Removed game error reported when GUI coordinates were off the room limits.
- Fixed crash in Direct3D renderer when alt+tabbing out of fullscreen mode.
- Fixed OpenGL fullscreen mode was not minimized when you alt+tab from it.
- Fixed Direct3D and OpenGL renderers unnecessarily applied anti-aliasing on utility sprites (used for transition effects) when "smooth scaled sprites" option was enabled.



What is new in 3.4.1

Common features:
- Upgraded Windows version of AGS with Allegro v4.4 library (previously v4.2).
- Implemented "RenderAtScreenResolution" game setting. When enabled, characters and objects are scaled in screen pixels rather than game pixels. (NOTE: it was always enabled for Direct3D in the past, but now you can set it to your liking)
- Implemented VerticalOffset and LineSpacing properties for fonts.
- Removed limit on Dialog Topics (was 500 topics per game).
- Removed length limit on the names of Inventory, GUI and GUI Controls.
- Removed length limit on the names of Hotspots and Objects.
- Removed length limit on event handler names.

Editor:
- Removed legacy game compiler.
- Raw compiled game data is now saved in "Compiled\Data" folder, as opposed to just "Compiled".
- The speech.vox file is now not recompiled if game is quick-run (using F5). Engine is supposed to find newer files in the Speech folder.
- Editor can now import games older than 2.72, and newer too (3.*) if you have extracted data files from compiled executable.
- ScriptAPIVersion and ScriptCompatibilityLevel settings now have "Highest" option, which is meant for automatically enabling newest script API when upgrading old project in a newer editor.
- Added new "Default Setup" pane, which works similarily to "General Settings" and lets you configure default values for game setup.
- Added "Font Height (pixels)" readonly property to the Font's pane, which works for both WFN and TTF fonts and may be used as a reference.
- Made Editor correctly detect modern versions of MS Windows for display on About dialog and when sending anonymous statistics.
- New application icon to comply with 3.4.0 splash screen.
- Fixed crash when importing old games which have extended editor version string saved in the project files.
- Fixed unhandled exception occuring when user types "#undef", "#ifdef" or "#ifndef" on the last line of the script.
- Fixed #ifver and #ifnver not working properly if version number had only one component (major version).
- Few improvements to the game compilation made in hope to reduce occasional data corruption.

Script:
- Fixed local variables not working in the switch's case expressions.
- Fixed Strings in switch, making them compare by value again.
- Fixed compiler mistakes caused by the use of objects of empty type (that is - struct without any variables in it).
- Fixed few cases of possible compiler crashing when there is an unfinished statement in the end of the script.

Script API:
- A new parameter StopMovementStyle is added to following functions: LockView, LockViewAligned, LockViewFrame, LockViewOffset, UnlockView. This parameter can be eStopMoving (default) or eKeepMoving.
- DynamicSprite.CreateFromFile and SaveToFile now support path tokens and comply to the new file path rules (no writing files to the game's installation directory).
- Added missing readonly properties to get Lighting/Tinting parameters for Character and Object: HasExplicitLight, HasExplicitTint, LightLevel, TintBlue, TintGreen, TintRed, TintSaturation, TintLuminance.
- Added Mouse.SelectPreviousMode() and Mouse.IsModeEnabled(CursorMode) functions.
- Added readonly properties to get Button's animation state: Button.Animating, Button.Frame, Button.Loop, Button.View.
- Added GetFontHeight(FontType) and GetFontLineSpacing(FontType) functions.
- Added setter for System.Windowed property, letting to change it at runtime, switching between windowed and fullscreen modes.
- Added System.RenderAtScreenResolution property to change sprite rendering mode at runtime.

Engine:
- Added OpenGL renderer to Windows version.
- Added support for switching between fullscreen and windowed modes at runtime using Alt+Enter key combination.
- All supported hardware-accelerated graphic drivers (Direct3D and OpenGL) now run every game in 32-bit display mode by default, and convert game's graphics on load if that is required. This fixes loss of green hue precision in 16-bit games and allows to run 8-bit games, although latter is only partially supported: there are color mismatches and dynamic palette cycling is not working.
- Partial support for plugins drawing on screen for hardware-accelerated renderers (Direct3D, OpenGL).
- Added support for global configuration file, which works as configuration for all games and overrides default game's config file. Individual game user's config overrides global one in its turn. Global config's location is platform-dependent (this feature is currently disabled on Windows).
- Implemented separate config option for game's shared data path, to keep it distinct from user-defined saves path.
- Engine saves last Windowed and RenderAtScreenResolution mode states to the user config file.
- Engine no longer writes and reads gamma level in saves, meaning that gamma keeps its current value when restoring a saved game.
- Removed arbitrary limit on number of sprites rendered at the same time for hardware-accelerated renderers (Direct3D and OpenGL) (was 75), and another limit imposed on drawing entries for all drivers (was 200).
- Engine now tries to get voice files from the Speech folder first, if one exists, and speech.vox later when quick-run from the Editor.
- Fixed speech portrait was displayed below GUI, contrary to speech text.
- Fixed ShakeScreen command was causing graphic artifacts when game is run with software renderer.
- Fixed calling Character.ChangeView during idle animation results in new view being animated.
- Fixed Speech.SkipStyle getter return value for eSkipTime case.
- Fixed Speech.VoiceMode not returning correct values when speech.vox is not enabled/present.
- Fixed AdjustVolumeWithScaling character's property not working with the new audio system.
- Fixed volume drop was not applied to audio clips which begin playing during speech voice-over.
- Fixed Game.SetAudioTypeSpeechVolumeDrop did not affect currently playing clips until next voice-over begins.
- Fixed Game.TranslationFilename returning "default" instead of empty string if no translation is set.
- Fixed engine was trying to locate "My Documents" folder on Windows Vista and higher even though it did not need it, and reporting internal error if such folder was not found, even though "Saved Games" folder is used instead.
- Properly toggle console upon play.debug_mode variable change in script.
- Added missing stubs for agsjoy plugin.

WinSetup:
- Fixed display mode selection was missing certain items.




KNOWN ISSUES (to be updated)

- iOS port is probably still not working with this version.
- When using Direct3D, game misses 1 bottom row and 1 rightmost column of pixels of game image when "Render sprites at screen resolution" is OFF. This also might cause slight image distortion. There's a suspicion that that is a bug in Microsoft's Direct3D driver since Windows 7.
- When running game in OpenGL fullscreen system cursor may be visible when over black borders.

Joseph DiPerla

Joseph DiPerla--- http://www.adventurestockpile.com
Play my Star Wars MMORPG: http://sw-bfs.com
See my Fiverr page for translation and other services: https://www.fiverr.com/josephdiperla
Google Plus Adventure Community: https://plus.google.com/communities/116504865864458899575

Snarky

I'm really excited about the editor improvements both in this version and the upcoming 3.4.2.
"QOL" is right: it'll make life a lot easier for game devs. Thanks! :-*

Crimson Wizard

I was going to improve Room zoom slider, making it possible to have downscaling too, but unlike with GUI the amount of affected code was pretty vast (unfortunately there is a severe case of code duplication), so I decided to postpone that for the next version.

Matti

Quote from: Snarky on Wed 11/07/2018 12:38:11
I'm really excited about the editor improvements both in this version and the upcoming 3.4.2.

+1

Great work. Many thanks for the updates!

Dave Gilbert


selmiak

The installer default-installs to an AGS3.4.0 directory. Or is this because I have ags3.4.0 installed there and it merely updated?

Crimson Wizard

Quote from: selmiak on Thu 19/07/2018 07:34:23
The installer default-installs to an AGS3.4.0 directory. Or is this because I have ags3.4.0 installed there and it merely updated?

AGS 3.4.0 or 3.4.1? Normally it should be one where you have installed 3.4.1 last time.

selmiak

NOW it's 3.4.1.14 :P
Maybe I did overwrite the 3.4.0 already with some other previous 3.4.1 version... just wanted to mention it...

Crimson Wizard

Quote from: selmiak on Thu 19/07/2018 10:36:52
NOW it's 3.4.1.14 :P
Maybe I did overwrite the 3.4.0 already with some other previous 3.4.1 version... just wanted to mention it...

Installer has a app GUID inside, and it saves last installation settings for this GUID in system config somewhere. We change GUID every time for a new version except for patches, to make the patch automatically overwrite the version it fixes.
There might be a way to still display path page in the install wizard, but no one was asking so far, so I forgot to check that out.

jmjm

Hiya! Thanks for all your hard work.

I'm making a text parser adventure game and I've come up against "too many nested if/else statements" when I'm using my:

if (Parser.Said("look blanket"))
{
}

else if (Parser.Said("look trophy"))
{
}

etc. etc. There are a lot of them! Awesome AGS forum folks helped me with a workaround for the GlobalScript, but now I'm coming up against the limit in my rooms, too. Is there any way to increase the number of allowed if/else statements, or do I have to MacGyver up something?

Thanks again for all you do.

Crimson Wizard

#11
Quote from: jmjm on Fri 27/07/2018 04:38:32
I'm making a text parser adventure game and I've come up against "too many nested if/else statements"

Wow.
Well, looking in the AGS code, that may be possible in theory to increase or remove this limit. But that would require some careful work with AGS compiler, so it's hard to promise when this happens and what future version this will be in.
What I'd like to know is what the "nested" mean in this case, is it if/else following each other or inside each other?

Quote from: jmjm on Fri 27/07/2018 04:38:32Awesome AGS forum folks helped me with a workaround for the GlobalScript, but now I'm coming up against the limit in my rooms, too.
Does not that workaround for GlobalScript also work for the room script? Could you post a link to your previous discussion?

LATER EDIT: I've just found the old topic: http://www.adventuregamestudio.co.uk/forums/index.php?topic=53817.0
And Snarky have already suggested almost same thing as I do here.

In the either case, I believe the simpliest workaround is to just split the function in two or more. For example:
Code: ags

function CheckParserMain()
{
    if (TryParserWords1()) return;
    if (TryParserWords2()) return;
    if (TryParserWords3()) return;
    ...
}

bool TryParserWords1()
{
    if (Parser.Said("look blanket"))
    {
    }
    else if (Parser.Said("look trophy"))
    {
    }
    else
    {
        // did not match anything
        return false;
    }

    // it will come here if player matched words correctly
    return true;
}


ALTERNATIVELY, there is command to match all parser input that starts with "nnn", like this:
Code: ags

if (Parser.Said("look rol"))


the "rol" means "any word".
So I believe you could do something like this:

Code: ags

if (Parser.Said("look rol"))
   ParseLook();
else if (Parser.Said("talk to rol"))
   ParseTalkTo();
...

where in ParseLook you will be checking only "look" combination, etc.

Joseph DiPerla

Doesnt AGS support case switch? Would that also work?
Joseph DiPerla--- http://www.adventurestockpile.com
Play my Star Wars MMORPG: http://sw-bfs.com
See my Fiverr page for translation and other services: https://www.fiverr.com/josephdiperla
Google Plus Adventure Community: https://plus.google.com/communities/116504865864458899575

Crimson Wizard

#13
Quote from: Joseph DiPerla on Fri 27/07/2018 16:23:44
Doesnt AGS support case switch? Would that also work?

There is no way you can use Parser.Said with switch, because you are not testing single result, but results of multiple function calls with different parameters until you find which works. The values at switch's "case" are constant expressions that must be known at compilation time.

(Also, Gurok knows better, but I guess switch may be using same internal mechanism for nested code blocks as if/else)

jmjm

Thanks for the thorough response plus finding and linking the old thread, Crimson Wizard!

I'm not strong on coding, I'm learning as I go. So I did manage to implement the workaround in my Global Script, but it was a while ago and I was unable to duplicate the results for my room. I was thinking it could've had something to do with possible differences between global and room scripts (as well as the rat's nest of code I'm making, despite my best efforts), but I clearly just missed something! I did manage to come up with a crude solution that works in a pinch, but this method is far more elegant.

I also like the idea of separating the parses according to their verb. That's also nice and neat.

I greatly appreciate all the help from AGS forum folks. I would've been stuck a few times without your guidance!

Quote from: Crimson Wizard on Fri 27/07/2018 10:47:41

Wow.
Well, looking in the AGS code, that may be possible in theory to increase or remove this limit. But that would require some careful work with AGS compiler, so it's hard to promise when this happens and what future version this will be in.
What I'd like to know is what the "nested" mean in this case, is it if/else following each other or inside each other?

Quote from: jmjm on Fri 27/07/2018 04:38:32Awesome AGS forum folks helped me with a workaround for the GlobalScript, but now I'm coming up against the limit in my rooms, too.
Does not that workaround for GlobalScript also work for the room script? Could you post a link to your previous discussion?

LATER EDIT: I've just found the old topic: http://www.adventuregamestudio.co.uk/forums/index.php?topic=53817.0


JFalcon

#15
Quote from: Crimson Wizard on Fri 27/07/2018 16:41:46
Quote from: Joseph DiPerla on Fri 27/07/2018 16:23:44
Doesnt AGS support case switch? Would that also work?

There is no way you can use Parser.Said with switch, because you are not testing single result, but results of multiple function calls with different parameters until you find which works. The values at switch's "case" are constant expressions that must be known at compilation time.

(Also, Gurok knows better, but I guess switch may be using same internal mechanism for nested code blocks as if/else)

Unless there is a limitation on the switch statement having a certain number of cases, the easiest thing to do would be to convert the resulting operation to a value that can be used within a switch...case from a loop.

The way that I would approach this using an array of structs, one the string that I would want to check and the other member with the value to use in the switch() case construct.  Each case could then dispatch to a method to handle that particular match.  For example:

Code: ags

    struct ParseDispatch {
       String text;
       int dispatchId;
    };

    ParseDispatch dispatch[2];

    dispatch[0].text = "look blanket";
    dispatch[0].id = 1;

    dispatch[1].text = "do something";
    dispatch[1].id = 2;


Now, after setting up the strings you want to check and declaring the functions you wish to call, you can use the loop to do the appropriate check and if you find a match that returns true from the Parser.Said() call, get the dispatch value and break from the loop:

Code: ags


int dispatchId = 0;

for (int i = 0; i < 2; i++) {
   if (Parser.Said(dispatch[i].text)) {
      dispatchId = dispatch[i].id;
      break;
   }
}

switch (dispatchId)
{
   case 1:
      LookAtBlanket();
      break;
   case 2:
      DoSomething();
      break;
   default:
      break;
}


Of course, this example is contrived and can be tidied up a bit.  You could use an enum value for dispatch IDs instead of hard coded numbers for readability or choose to use the loop counter as the ID for a match and just use an array of Strings instead of structs.

That being said, is there a limitation on the number of case statements in a switch?

Crimson Wizard

#16
Quote from: JFalcon on Thu 09/08/2018 10:06:08
That being said, is there a limitation on the number of case statements in a switch?

I checked the code, and "switch" uses same mechanism to keep record of nested script blocks as if/else, having same limit of 75.

Quote from: JFalcon on Thu 09/08/2018 10:06:08the easiest thing to do would be to convert the resulting operation to a value that can be used within a switch...case from a loop.

The way that I would approach this using an array of structs, one the string that I would want to check and the other member with the value to use in the switch() case construct.

Ahh, yes, you are right, that will work. I was not thinking hard enough earlier.

Although I'd perhaps propose to again split this into verb ID and object ID to make further handling more convenient; for example, you will be able to run some specific commands in case of each "look", or tell "I cannot look at xxx" if the object is unknown, etc.
And of course there are still ways to split the giant switch into several parts to make it work in current AGS.

JFalcon

Quote from: Crimson Wizard on Thu 09/08/2018 10:18:22
Although I'd perhaps propose to again split this into verb ID and object ID to make further handling more convenient; for example, you will be able to run some specific commands in case of each "look", or tell "I cannot look at xxx" if the object is unknown, etc.
And of course there are still ways to split the giant switch into several parts to make it work in current AGS.

Splitting it up will definitely allow it to fan out further and get past that particular limitation.  What I found interesting was that structs could have functions which allow them to access its members using the 'this' keyword.  Unfortunately though, they don't have the ability to store any type of function "pointer".  If this were possible, then the for() loop method could find the matching word, call through the function pointer and break from the loop (arbitrarily repeating this method for sub-commands as you suggest); but alas....

Gurok

Quote from: Crimson Wizard on Thu 09/08/2018 10:18:22
Quote from: JFalcon on Thu 09/08/2018 10:06:08
That being said, is there a limitation on the number of case statements in a switch?

I checked the code, and "switch" uses same mechanism to keep record of nested script blocks as if/else, having same limit of 75.

Quote from: JFalcon on Thu 09/08/2018 10:06:08the easiest thing to do would be to convert the resulting operation to a value that can be used within a switch...case from a loop.

The way that I would approach this using an array of structs, one the string that I would want to check and the other member with the value to use in the switch() case construct.

Ahh, yes, you are right, that will work. I was not thinking hard enough earlier.

Although I'd perhaps propose to again split this into verb ID and object ID to make further handling more convenient; for example, you will be able to run some specific commands in case of each "look", or tell "I cannot look at xxx" if the object is unknown, etc.
And of course there are still ways to split the giant switch into several parts to make it work in current AGS.

Sorry, I might be late to the party here, but I need to correct a few things.

The switch statement does indeed use the same mechanism for managing nesting as if/else blocks. However, case statements are not additional layers of nesting. You can certainly have more than 75 case statements in a single switch block. You just can't have more than 75 switch blocks inside each other.

The switch statement in AGS is very flexible. It's more like a destructured if statement than the restrictive kind you might find in C or old Java. The following construction is certainly possible and will work:

Code: ags
switch(true)
{
    case Parser.Said("One"):
        break;
    case Parser.Said("Two"):
        break;
    ...
}

[img]http://7d4iqnx.gif;rWRLUuw.gi

Crimson Wizard

#19
Quote from: Gurok on Wed 22/08/2018 08:10:01
The switch statement in AGS is very flexible. It's more like a destructured if statement than the restrictive kind you might find in C or old Java. The following construction is certainly possible and will work:

I had no idea about this... May this be added to the manual? Because it mentions "constant expressions" right now.

SMF spam blocked by CleanTalk