Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - Crimson Wizard

#321
Updated to Alpha 21
(Please use download links in the first post)

This update contains all the new features and fixes from 3.6.2 RC3 (excepts ones related to backwards compatibility).

Editor:
- In General Settings added "GUI common controls handle only left mouse button" option.
- Fixed default values for Character and Object's Enabled and Visible properties set when upgrading a pre-4.0 game project.
- Fixed default value for "Use old-style voice clip naming rule" setting set when upgrading from older 4.0 alpha versions.
- Fixed newly created WFN fonts had their size multiplier property discarded when a game is compiled.

Compiler:
- Fixed a bug where naming a parameter like its function led to a crash.

Scripting:
- Support regular (non-managed) struct and array variable initializers, where you can specify their element values either in the order of their declaration or as a "name1: value, name2: value" sequence. For arrays the latter would be "0: value, 1: value" and so forth.
  NOTE: this works only for global variables at the moment.

Script API:
- Added DialogOptionsNumbering enum, to use when setting dialog options numbering mode.
- Added multiple new properties to Dialog type: OptionsBulletGraphic, OptionsGap, OptionsGUI, OptionsGUIX, OptionsGUIY, OptionsHighlightColor, OptionsMaxGUIWidth, OptionsMinGUIWidth, OptionsNumbering, OptionsPaddingX, OptionsPaddingY, OptionsReadColor, OptionTextAlignment. Most of these are replacing previously existing old-style variables in "game" struct and OPT_* options. OptionsGUIX/Y and OptionTextAlignment are completely new features.
- Added new game-wide option OPT_GUICONTROLMOUSEBUT that defines whether common GUI controls are affected by the right mouse button or not (InventoryWindows are excluded from this, because they have their own special handling for RMB).

Engine:
- Standard Dialog options now support Right-to-left text mode.
- Fixed a number of Room's script indexed properties not working correctly, such as: Room.Hotspots[], Room.Objects[], Room.Regions[], Room.WalkableAreas[], Room.Walkbehinds[].
- Fixed blend modes not handled correctly by Software renderer.
- Fixed certain blend modes not respecting transparency with OpenGL renderer.
- Fixed default dialog options highlight color had wrong value.
- Fixed Character.FaceDirection() not respecting blocking style parameter.
- Fixed characters and objects not making last planned step when moving.



This update has a new script syntax feature that allows to initialize a struct or array using a "initializer list". Unfortunately, this feature was not fully completed, and only works for global variables. There's a chance that it will be expanded to local variables too in the future updates.

Example for structs:
Code: ags
struct Location 
{ 
    float Longitude, Latitude; 
};
struct PointOfInterest
{
    int AdmissionFee;
    Location WhereItIs;
};

PointOfInterest EiffelTower = {
        WhereItIs: { Longitude: 48.8584, Latitude: 2.2945 }, 
        AdmissionFee: 20 + 3,    // ← Simple 'int' or 'float' expressions are possible
};

Example for arrays:
Code: ags
int Primes[10] = { 2, 3, 5, 7 };
Code: ags
bool IsPrime[10] = {
    2: true,     // ← means, IsPrime[2] is 'true'
    3: true,     // ← means, IsPrime[3] is 'true' etc.
    5: true,
    7: true,
};
#322
There's a problem with the manual, in the description to GiveScore it never mentions or references game variables, but sais "Adds SCORE to the player's score." I suppose it's easy to misunderstand that as that score is a part of the "player" object in script.

I will add a correction there.
#323
Quote from: Jleger91 on Sun 13/04/2025 22:42:22One other question I have is "will my save data be distributed to other peoples computer"?

Of course not, saved games are stored in user documents:
https://adventuregamestudio.github.io/ags-manual/RuntimeEngine.html#game-saves
#324
Updated to Release Candidate 3
(Please use download links in the first post)

Contains all fixes from 3.6.1 Patch 10

Own changes:

Editor:
- Added a readonly "ProjectFilename" property to Fonts, which displays their in-project file name.
- Added "Palette index" selection for sprite's import transparency option.
- Added "Change Room Number" context menu command for the Rooms in Project Explorer.
- Fixed importing GIFs with "palette 0 / N" transparency option would refer a palette color from each individual frame's palette rather than the original GIF palette, which could lead to wrong colors used as transparents.
- Fixed Autocomplete failing in case of UNIX line endings in script file.
- Fixed Font preview could crash the Editor with out of memory error in case of a very big font.
- Fixed Editor won't won't let change existing TTF font's size if SourceFilename property is not set for any reason.
- Fixed Frame index not applied when importing sprites from a GIF (regression since 3.6.2 Beta).
- Fixed unhandled exception occuring when user right-clicks or double clicks on a informative message in the Output panel.

Script API:
- Added Room.BackgroundCount readonly property.
- Added GetWalkBehindBase() function, complementing SetWalkBehindBase().

Engine:
- Fixed GUI controls with transparency are not drawn correctly by the Software renderer.
- Fixed DynamicSprite.Rotate mistreating "degrees" argument.
#325
Quote from: Baguettator on Sun 13/04/2025 21:04:22EDIT : OK, it was an error from me, but the compiler didn't indicate the right error/line : it was because I declared "int ressource" just before, but the problem is that "ressource" is already an int[][] in my script. The compiler should have told that "ressource already exists !

Where exactly did you declare that other "ressource"?

It's allowed to declare another variable of the same name in a different scope. That is a common behavior in programming languages.

For example, if you have a global variable VARIABLE, you may still declare a local variable VARIABLE inside a function, and it will override the global one for the duration of that function.
#326
Quote from: Baguettator on Sun 13/04/2025 20:06:29I encounter a problem, it seems a bug from the v4 compiler.

Here's my code:

Code: ags
int ressource[TOTAL_RESSOURCES, TOTAL_CATEGORIES_RESSOURCES];
[...]
Ressource1[0].Text=String.Format("%d", ressource[nourriture][colo]); // This is line 1171

And the compiler displays an error :
Struct_Events_Colonie.asc(1171): An array index cannot follow an expression of type 'int'

Testing this kind of array in an empty project, accessing its elements seem to work.
Please give more details about the variables that you use here:

nourriture,
colo,
Ressource1.

Maybe break this long expression into smaller ones, that might help finding which exactly part has the error. Like this:
Code: ags
int num = ressource[nourriture][colo];
String str = String.Format("%d", num );
Ressource1[0].Text = str;

Other than that, if you are using variables from another script, double check that you have declared an import EXACTLY same way as the variable itself.
#328
AGS 3.6.1 - Patch 10
Full release number: 3.6.1.32


For Editor
Spoiler

For Android
Spoiler
NOTE: the Editor now includes Android build component letting you prepare your own games for Android
[close]

For Engine/Editor developers
Spoiler


Released: 13th April 2025

Previous stable version: AGS 3.6.0 P13 forum thread


This release is brought to you by:

- Alan v.Drake (fixes, improvements)
- Crimson Wizard
- Donovan Watteau (fixes)
- edmundito (iOS fixes)
- eri0o
- mausimus (Text Parser fixes)
- Walter Agazzi (fixes)



Summary

3.6.1 update focuses mainly on improving performance and usability of existing features, in both Editor and Engine.

The noteable addition to the Editor is a "Log Panel", which lets you read game logs right in the editor's window. "Goto definition" now works on game object script names and opens their respective panels. Room editor features better panning and zoom controls. Views allow to select and modify multiple frames at once.

In the engine, there's a significant improvement to script performance, which may make script-heavy games run 30-40% faster compared to AGS 3.6.0 (these were real test results on a certain game with 3D simulation). There's a big improvement to the speed of manipulating Overlays, and general speed improvement of graphics rendering primarily useful for high resolution games.

There are other fixes and improvements to various parts of the program too.
Please be sure to read "Upgrading to AGS 3.6.1" topic in the manual: https://adventuregamestudio.github.io/ags-manual/UpgradeTo361.html


Changes in the Patch 10:

Editor:
 - Fixed a check for an imported room mask size did not correctly account for the room's mask resolution setting (it worked, but mishandled some edge cases).
 - Fixed exceptions occuring when reimporting a sprite or a audio clip from source, if the source filename string was wrapped in double quotes.
 - Fixed script variables generation could sometimes produce a non-latin character in a variable name if the Editor is running on a system with non-English current locale.
 - Fixed '\n' linebreaks not saved correctly in dialog option strings.
 - Fixed translation compiler mistreating escaped opening bracket in a text line (`"\["`);
   it must keep it as-is, because "[" char is a old-style line break in AGS.
 - Fixed LogPanel not applying filter settings right after they were changed.

Engine:
 - Fixed a AudioChannel did not report a correct Position right after a AudioClip.PlayFrom() call.
 - Fixed Button resizing to sprite 0 size if NormalGraphic is set to 0 (default button look).
 - Fixed Character movement recalculation when changing move speeds while walking, and movement path contains 45-degrees diagonal segments.
 - Fixed a solid Character (serving an obstacle) can get ignored by a walking Character, if the obstacle character's position appears within the walking character's own blocking zone.
   (This seems to be a redundant condition introduced very long time ago in the engine by mistake.)
 - Fixed object's look not updated after it was assigned a dynamic sprite, redrawn, sprite deleted, object redrawn without a sprite (used a placeholder), and then another dynamic sprite assigned with coincidentally the same number.
 - Fixed font outline index limited to 127 (although we theoretically support higher font numbers).
 - Fixed font outline parameters not initialized correctly if engine is built by a system that treats "char" as unsigned 8-bit type.
 - Fixed a crash which occured when script mistakenly tried to call RunInteraction() for a inventory item 0.
 - Fixed loading translation entries larger than 1024 bytes.
 - Fixed SDL log level was defaulting to "verbose" if not read from config (should be "info").

WinSetup:
 - Fixed "Save and Run" command sometimes caused 2 engine processes, one of which terminated later.
   This did not prevent a game from running, but could result in temporary CPU and memory overload.


Changes in the Patch 9:

Editor:
 - Fixed dragging an item to a folder in Project Explorer might cause that item to visibly appear in a wrong folder, if there are folders which name differ only in letter case.

Engine:
 - Fixed Character.Animate() could cause game to error reporting "invalid loop" if this character was idling at the time, and Character.LockView() was not called prior to Animate(). (This is a regression in 3.6.1)
 - Fixed inventory cursor hotspot (crosshair) not drawn properly over item sprites with alpha.

OSX:
 - Fixed location of global config file: was in game installation directory, now in "Library/Application Support/uk.co.adventuregamestudio".


Changes in the Patch 8:

Editor:
 - Fixed game cannot be loaded if its GameFileName setting is an empty string.
 - Fixed pressing Alt was not selecting Main Menu.
 - Fixed error occuring when trying to assign an image to the multiple selected View Frames if they have different initial images.
 - Fixed script preprocessor directive "#else" in the nested conditions.

Engine:
 - Made File.ReadStringBack() support reading back strings without null-terminator in the end
   (ReadStringBack() reads a string, which has its length prepended to the sequence of chars).
 - Improved graphic mode selection when game window is moved to a secondary monitor.
   Note that still not all graphic setups are reliable on secondary monitors, specifically "real fullscreen" mode may be behaving unexpectedly if you try to switch to it on non-primary display.
 - Fixed AudioChannel's Paused state is not saved when saving the game.
 - Fixed error in case a character was walking while being locked to a temporary View, and switched to a directional loop which does not exist in the locked view.
 - Fixed active item cursor's image may duplicate itself onto other cursors under certain conditions.
   (this is regression since 3.6.1 Patch 6)
 - Fixed Inventory Window in automatic mode not redrawing its contents immediately when player character changes.
 - Fixed ListBox.FillDirList() may add case-sensitive duplicates on platforms with case-sensitive filesystems.
 - Fixed room's fade-out effect playing while skipping a cutscene (it must skip instantly).
 - Fixed FadeOut or FadeIn not toggling screen state if they are inside a skipped cutscene. This could have resulted in screen not turning to black or not restored as expected if cutscene was skipped by player.
 - Fixed Wait() delay of value > 32k would be treated as infinite timeout.
 - Fixed Ctrl + Alt key combination not working (toggle mouse lock). This is a regression in 3.6.1.
 - Fixed game may fail loading on platforms with strict memory alignment (e.g. MIPS processors).

Compatibility:
 - Fixed SetCharacterViewEx() not treating "align" parameter according to old-style set of values.
 - Fixed SetTextOverlay() could cause internal mistakes leading to unexpected errors in game.
 - Fixed Wait() calls for pre-3.6.0 versions of Script API, where negative delay was treated as 0.

WinSetup:
 - Fixed setup not distinguishing "desktop resolution" and "native resolution" from explicit resolution sizes when saving or loading config. Made sure that it remembers exactly the choice that user made ("desktop", "game resolution" or explicit resolution size).
 - Fixed "native game resolution" not present in the list if it equals desktop resolution.
 - Fixed nearest resolution selection in case config requested a resolution equal to the native game's resolution, but that resolution was not among the supported ones.


Changes in the Patch 7:

Engine:
 - Hotfix mouse cursor not being drawn sometimes after changing rooms (regression in 3.6.1 P6).


Changes in the Patch 6:

Editor:
 - Fixed Ctrl+C and Ctrl+V not working in GUI editor.
 - Fixed sprite export and copying a sprite to clipboard operations were always exporting a 32-bit image, regardless of the actual sprite's color depth.
 - Fixed "Recreate spritefile" command was unintentionally converting any sprite to 32-bit if its source was not found, and it was taking existing image from the old spritefile.

Engine:
 - Fixed Software renderer could crash the game under some circumstances when the sprite cache's limit is exceeded (this is a regression in 3.6.1).
 - Fixed text-based lipsync's frame delay calculation: the existing formula was causing the delay value to "jump" back and forth with the slightest difference of speech text length, resulting in the speech lines of close length to be played with the notably different animation speeds.
 - Fixed drawing a 32-bit sprites on a 8-bit surface (e.g. a room mask), it was done wrong and was causing a memory corruption too.
 - Fixed drawing a room's walkable mask in script could cause errors during character walking if used colors exceeded walkable area number limit.
 - Fixed walk-behinds not drawn over characters and objects anymore (regardless of their baselines) after walk-behind mask was changed using drawing operations in script.
 - Fixed Game.SimulateKeyPress() not working in "old key-handling mode" (regression since 3.6.0).
 - Fixed script location is not reported in case of logical errors in engine's functions (regression since 3.6.0).

WinSetup:
 - Removed an obscure "Use 85 Hz display" option.


Changes in the Patch 5:

Editor:
 - When the room background size changes, clamp Room Edges to the new size.
 - Fixed Editor refusing to load a project if its folder name exceeds 40 characters.
   (An obsolete historical limitation which we forgot to cut from the program.)

Compiler:
 - Fixed script compilation hanging forever if a non-latin unicode character is met in script (outside of comments).

Engine:
 - Fixed GUI.ProcessClick() using mouse position when detecting a GUI control, instead of the position passed in the argument list.
 - Fixed Region.GetAtScreenXY() was returning null for offscreen coordinates. Made it return region[0] for consistency with other room areas, and backwards compatibility.
 - Fixed room Overlays not sorted in the order of their creation, like screen Overlays.
 - Fixed a potential mistake in Lucas-Arts speech position when there are multiple room viewports and speaking character is not directly visible in any of them.
 - Fixed Engine could switch program's locale to the current system locale by mistake when player is typing text. This could potentially lead to random glitches in text input in games which are run in ASCII mode and are handling extended characters.
 - Fixed TextBox was trying to display unsupported characters (in ASCII mode), resulting in random garbage.


Changes in the Patch 4:

Editor:
 - Fixed extracting templates with very large files inside would cause "Out of memory" error.
 - Fixed crash occuring when trying to import a non-existant GIF frame during Sprite Import.
 - Fixed potential mistake with sprite transparency occuring when importing a 8-bit sprite into 16/32-bit game.

Compiler:
 - Fixed "\t" (and few other less common escaped chars) not handled properly when they are inside string literals.
 - Fixed a crash in compiler occuring if user script defined a variadic function.
   (User-defined variadic functions are not properly usable at the moment, but this at least prevents an unhandled exception.)

Scripting:
 - Declare "UNICODE" macro for scripts if game is made in unicode mode.

Script API:
 - Added a number of missing OPT_* constants used with Get/SetGameOption functions.

Engine:
 - Fixed setting Screen.AutoSizeViewportOnRoomLoad to false in "game_start" could cause primary viewport and camera become initialized with zero width and height.
 - Fixed setting camera's size in "game_start" would unexpectedly get camera clamped to 320x200.
 - Fixed number of mistakes in Text Parser occuring when handling "multiwords".


Changes in the Patch 3:

Editor:
 - Fixed that after deleting a View's frame editor did not select next frame (regression in 3.6.1).
 - Fixed "Delete last loop" button not appearing in the View Editor if the view is filled using "Assign sprites to view" command from the Sprite Manager.

Engine:
 - Implemented an alternate solution for rendering "bad" TTF fonts that does not increase their loading times (after previous patch 2).
 - Allow scene render during "load room" event if the last room transition was "Instant".
   This has to be done because number of games used this event for custom transitions.
 - For games compiled in "Debug" mode "warnings.log" file will be written in "savegame dir" on platforms where modifying game directory is forbidden in principle (OSX, iOS, Android, Web).
 - Fixed System.Log() was registered for plugins using a wrong argument list.

Compatibility:
 - Fixed loading of 3.5.0 saves (broken in 3.6.1).

Windows:
 - Fixed disk space check was testing space in the current directory instead of the save game location.


Changes in the Patch 2:

Editor:
 - Fixed few potential program errors for "Generate Keystore" in Android preferences.
 - Fixed external processes (such as test game runs) were started using ShellExecute, which could theoretically lead to unintended results.

Engine:
 - Fixed String.Replace crashing the engine if the resulting string exceeds 3000 bytes.
 - Fixed releasing a mouse button could cause double "on_event" call (with eEventGUIMouseUp).
 - Improved rendering of TTF fonts which have glyph sizes surpassing declared font's height.
   This fixes the look of text on gui controls, and automatic outlining on these fonts.
 - Fixed a dialog shown with InputBox() function drawing typed text beyond text box'es border.
 - Fixed custom dialog options in the "old mode" not triggering redraw when the active option changes.


Changes in the Patch 1:

Editor:
- Fixed View's frame preview sometimes drawn incorrectly, in case of certain panel sizes.
- Fixed folding in the script editor not working correctly if there's a commented closing bracket ("//}") inside this code section.
- Fixed Editor sometimes failing to update game exe's file information and/or icons, if user was importing any sprites during this working session.

Engine:
- Fixed room objects not updating under Direct3D/OpenGL renderer, if they were assigned a dynamic sprite, then that sprite was deleted, and a new one assigned with coincidentally same ID.
- Fixed room objects not updating under Software renderer, if they were assigned a dynamic sprite, and that sprite was modified while object was not visible on screen.
- Fixed inventory cursor's crosshair not displayed (when enabled in game settings).



What is new in 3.6.1

Common features:
- Implemented Deflate compression option for sprites.
- Removed length limits for: Game name, savegame folder, Character's script name and regular name (description), Inventory item's name (description), Mouse cursor's script name, Audioclip's script name.

Editor:
- Discontinued Source control integration functionality, removed "Put sound and sprite files in source control" option from General Settings.
- In General Settings moved few properties to different groups for better consistency.
- Added "Scale Character sprite offsets" property to General Settings. This property refers to scaling of Character.z and sprite offsets added by LockViewOffset script command.
- Added TextureCacheSize and SoundCacheSize properties to Default Setup. These let configure the sizes of runtime texture and sound cache sizes respectively.
- Added "Leave room after fade-out" event to Rooms (called "Unload" by default).
- Added Translated property to all GUI Controls (was available only in ListBox). Translated property tells whether this control's text has to be translated, and applied text direction (in right-to-left text mode).
- Support '\n' linebreak character in the Label's Text and potentially other text properties.
- Improved Room Editor controls:
  Added free panning mode done by holding the middle mouse button, or alternatively - by holding Space + LMB.
  Mouse Wheel without key modifiers scrolls the room vertically; Shift + Mouse Wheel scrolls the room horizontally.
  Zoom is done by Ctrl + Mouse Wheel and room now zooms towards or outwards the cursor position.
- In Room Editor the context menu is now displayed by RMB or Shift + RMB while editing masks.
  The individual room mode menu is merged with the "copy coordinates" command when shown.
- In Room Editor the hint with coordinates is now also displayed when moving Objects or Characters with keyboard.
- In Dialog Script editor support most Edit menu and context menu commands from the regular Script editor, with a few exceptions.
- In Sprite Manager added command "View" -> "Show filenames" which toggles display of a sprite's source filename under the sprites.
- Adjust sprites' import settings after "Crop sprite edges" command; this would ensure that these sprites are restored from source file keeping their cropped sizes.
- During sprite export Editor will display a proper progress dialog.
- Zoom controls in Character and View panes now allow downscaling too. View editor displays the preview sprite stretched to fill the parent panel.
- View editor now allows to select multiple frames at once, across multiple loops too, using standard Shift + LMB and Ctrl + LMB combinations. Properties panel lets modify properties for all the selected frames at once.
- Added "Replace with all sprites from folder" command to the View editor's context menu.
- For Audio Clips in the project tree added "Force Reimport", "Force reimport all file(s)" and "Replace Source File" context menu commands.
- For Output Panel added "Copy selection" context menu command.
- Implemented Log Panel that lets you see the engine and game logs right in the Editor.
- Improved LipSync panel looks in case user's system has display scaling option enabled.
- "Goto Definition" command in script will now work for most of the game entities too, such as Characters, GUIs, and so forth. In that case it will find a game's entity and open a respective editor panel for it. This still does not work for some types, such as Room objects, and Views.
- Added main menu commands for opening a Project folder and Compiled folder.
- Added "Export Global Messages to script" menu command. This command is meant for upgraded pre-3.2 game projects, and will generate a script with a String array, moving global messages texts there.
- For script's tabs added a context menu command for opening this script's location.
- When run with "/compile" argument Editor will print all messages to the console (stdout), instead of displaying modal message windows.
- For Android build target Editor now supports a directory to place plugins in.
- When building a game for Android and Linux the Editor will now be more tolerant to missing plugins and only issue a warning instead of stopping with error.
- Config will now be saved in UTF-8, letting to support setup program's title text in unicode.
- For non-Windows build targets Editor will fix config containing Direct3D graphics driver option and set OpenGL instead.
- For Color Themes: implemented character literal, braces match and braces error settings.
- Made Editor be somewhat more tolerate to missing XML nodes in Game.agf, in many cases it will still let open a game.
- When upgrading older game projects, Editor will insert a call to SetRestartPoint() in the end of the 'game_start' function in GlobalScript.asc. This is done to complement removal of an automatic restart point in the engine. This inserted command is safe to remove.
- When upgrading pre-3.2 rooms with disabled SaveLoadEnabled property the Editor will reset this property and insert a comment with a warning into the corresponding room's script. This is done because this property is deprecated as is no longer accessible.
- Fixed Editor refusing to open a game if one of the translation files is missing.
- Fixed General Settings and Default Setup not working correctly right after importing a pre-3.* game project.
- Fixed importing GIFs or 8-bit PNGs may lose transparent pixels if source images used other palette index than 0 for transparency.
- Fixed Project Explorer's folders collapsing after certain user actions, such as dragging items or renaming things.
- Fixed deleting collapsed "region" in script would sometimes lead to portion of the script undeleted but staying invisible.
- (Possibly) Fixed a "Index out of range" exception in Script editor, related to the "script location" drop-down list, which could occur at random circumstances while
  working with the script, and any Color Theme is enabled.
- Fixed Editor could miss some of the files when cleaning up old compiled files after the Game's Filename property is changed.

Scripting:
- Support "#else" preprocessor directive.

Script API:
- Implemented Room's "After fade-out" event.
- Added eEventLeaveRoomAfterFadeout event for the global "on_event".
- Added eEventGameSaved event which runs after game was saved.
- Expanded interaction functions for Character, Object, InventoryItem, Hotspot and Region types: now they all receive respective object's pointer as a parameter, similar to GUI event functions, as well as a cursor mode this interaction was run with, if applicable.
- Added Game.ResetDoOnceOnly(), which completely resets all DoOnceOnly instances.
- Added Game.PrecacheSprite() and Game.PrecacheView(), which preload certain sprites and linked frame sounds into the engine's sprite cache memory.
- Added ScriptName property to AudioClip, Character, Dialog, GUI, GUIObject, Hotspot, InventoryItem, Object.
- Added static GetByName() function to AudioClip, Character, Dialog, GUI, GUIObject, Hotspot, InventoryItem, Object.
- Added Object.AnimationVolume property, which works similar to Character.AnimationVolume.
- Added static File.ResolvePath() and File.Path attribute.
- Added support for a text formatting to a number of functions: DisplayAtY(), Character.SayAt(), Character.SayBackground(), DrawingSurface.DrawStringWrapped().

Engine:
- Updated to SDL 2.28.5 and SDL_Sound 2.0.3+.
- Significant performance improvement to scripts. Script running speed restored to a level close to AGS 3.2.1. Testing few "script-heavy" games showed fps raise by up to 30-40% compared with 3.6.0 engine.
- Improved performance of String objects in script.
  For instance, appending a character to a String is now roughly x2 times faster, *sequential* iteration of String.Chars[] in Unicode mode is about x12 (!) times faster (Strings in ASCII mode have relatively less improvement, because they have been faster than Unicode mode already).
- Improved performance when creating, deleting and manipulating Overlays; allows the game to have thousands of those with much less slowing down.
- Improved performance when updating and deleting dynamic sprites, and notifying any objects that have to redraw themselves. Engine no longer resets Graphic properties of objects referencing deleted dynamic sprite to 0.
- Implemented "texture cache", in addition to the existing "sprite cache". The texture cache keeps textures generated from raw sprites and lets reusing them, improving performance and reducing CPU workload. The actual impact is proportional to the game's resolution and amount of simultaneously animated objects on screen.
- WFN font renderer now too supports unicode mode and renders texts in utf-8, so long as the font contains glyphs of corresponding indexes.
- Buttons, ListBoxes and TextBoxes now support Right-to-left text direction.
- DrawingSurface.DrawString now supports Right-to-left text direction.
- All the script File functions now treat paths in case-insensitive way (including subdirs), which makes them platform-independent.
- Removed an automatic SetRestartPoint() call at startup. This is done in case user does not want to use default "restart" save slot, or has a custom save system.
- Support handling multiple mouse clicks per game frame, similar to how multiple key presses were supported since 3.6.0.
- When starting up, engine will now precache only first 4 or 8 loops of the starting player character's View. This is done to avoid filling sprite cache with too much sprites at once in case when the player's View contains lots of additional animations.
- Characters will now have their graphic offsets, set by Character.z property and LockViewOffset() function, scaled along with the character's own scaling. This is done so long as the respective game option is enabled in the General Settings.
- Ensure that character and object scaling is updated even when the game is not drawn. This fixes rare issues when their scale property did not update in time whilst the game was completely fadeout, and similar cases.
- Allow to change Character's move speed while its moving.
- When Character is ordered a new move command while already moving, the engine will try to make a smooth transition between old and new moving without a delay.
- Ensure that when Overlays have identical ZOrder they will be sorted in the order of their creation. Besides convenience, this is also meant to restore historical behavior from before Overlay.ZOrder property was introduced.
- Allow game to call DynamicSprite.CreateFromDrawingSurface() and CreateFromBackground() with zero or negative size, clamping it to 1x1, in consistency with Create().
- Engine will now log a warning for the most incorrect parameters to Animate function instead of quitting the game.
- Engine will now skip blocking Character.Say commands instantly while skipping a cutscene.
- Object.SetView now lets invalid loop and frame values, and fallbacks to using loop 0, frame 0, printing a warning. This is also consistent with backwards-compatble SetObjectFrame() behavior.
- Changed Object.SetView() to not play a frame's sound, which could lead to a duplicated sound play if Object.Animate is run right after.
- Text Overlays internal images are now registered as dynamic sprites, and their IDs may be read from Overlay.Graphic. This lets find out their sizes using Game.SpriteWidth/SpriteHeight and optionally draw them somewhere using DrawingSurface.DrawImage.
- Ensure all the script API is now correctly available for the plugins.
- Engine will now safeguard plugin's reading and writing of game saves, so that any mistakes done by plugins won't affect other parts of a save.
- Engine will disable vsync in a "infinite fps" mode, because vsync prevents getting more fps.
- Engine will force any in-game debug messages to be displayed in message boxes, disregarding game's "Display all messages as speech" option.
- Display critical alerts as system modal messages on all platforms that support that (unless engine is run with "--no-message-box" parameter).
- Print some info about memory usage when reporting a "Out of memory" error.
- Deprecated in-game "console", as practically useless.
- Added new config settings in "graphics" section: "sprite_cache_size" (which replaces deprecated "cachemax" in "misc") and "texture_cache_size".
- Fixed Characters may be seemingly "walking in place" for some time when arriving at destination.
- Fixed Display and Say commands treating the second met "&" sign as a voice-over token too (they must only check the first one in string).
- Fixed PlayMP3File() function limiting filename argument by an arbitrary number of characters.
- Fixed speechlines were adjusting their Y position while trying to not overlap GUIs even when these GUIs are completely offscreen.
- Fixed first Sierra-style speechline in a sequence was adjusting its Y position without need when GUIs are set to be hidden during game pause (this includes blocking speech). Normally, the speechlines are adjusting their Y position in order to not overlap GUIs, but when GUIs are hiding during speech there should not be any need to do so.
- Fixed script behavior in case a local variable was assigned a value without being initialized with a zero memory by compiler's intruction beforehand. This is not a problem with the standard compiler, but technically could be an issue with any custom implementation.
- Fixed old-style letterbox viewport getting broken after loading an old pre-3.5.0 save.

Engine Plugin API:
- Added IAGSStream interface, IAGSEngine.OpenFileStream() and GetFileStreamByHandle().
- Added IAGSEngine.ResolveFilePath() method, which resolves a script path (with location tokens) into a proper system filepath.
- Fixed IAGSEngine.GetFontType() incorrectly reporting TTF font type for WFN fonts with more than 128 characters.

Compatibility:
- In Editor, restored all the Character's variables available in "backward-compatible" mode. This is primarily to make it easier to import very old games.
- Allow to run an animation over a loop with zero frames, by using the placeholder frame. This lets particular old games to continue running instead of crashing with error.
- Fixed slower character walking speeds in pre-3.1 upscaled and high-resolution games.
- Fixed Object.SetView() and SetObjectFrame() not treating -1 for loop and frame as "keep previous values" in older games.
- Fixed inventory window not updated after game.top_inv_item is assigned a new value.
- Fixed a "New Room" command in old-style dialog scripts was preventing "First time Enter room" event to be called.

Windows:
- 32-bit Windows engine is now built as "large address aware" program, which will allow it to use up to 3 GB of RAM on 32-bit systems and 4 GB of RAM on 64-bit systems (was 2 GB previously).

iOS:
- Updated port for 3.6.*.

Web / Emscripten:
- Fixed Safari cannot switch the game into fullscreen mode.

WinSetup:
- Added options for setting texture cache and sound cache size.
- Added options to disable particular graphic drivers and graphic driver selection, and fullscreen mode selection.




Thanks to everyone who contributed to and tested this version!



#329
Quote from: Jleger91 on Sun 13/04/2025 20:04:37I'm setting up a Steamworks account to distribute the finished game; what do I upload? Do I only upload the "Compiled" folder that contains the .exe and related files or do I need to include other stuff?  :confused:  :tongue:

This is not really related to Steam, but distributing your game anywhere.

The Compiled folder contains multiple subfolders, each for one platform: Windows, Linux, Android etc.
The Compiled/Data folder contains raw game data in case you need that for some reasons. Usually this may be used if you are preparing a game version for the platform which is not supported by AGS Editor directly, such as Mac OS or iOS.

So if you prepare a build for Windows, then take only files from Compiled/Windows,
if you prepare a build for Linux, then take only files from Compiled/Linux,
and so on.

This is all explained in the manual:
https://adventuregamestudio.github.io/ags-manual/DistGame.html
#330
Overview

Following a recent request (see issue 2705),
I started working on an experimental feature which would allow to attach custom pixel shaders to game objects in AGS 4.0.

THIS POST WAS UPDATED TO COVER THE LATEST STATE

The two PRs with shaders support was merged into AGS 4 branch:
https://github.com/adventuregamestudio/ags/pull/2716
https://github.com/adventuregamestudio/ags/pull/2733
This feature is now a part of AGS 4 since Alpha 22 update. Please see the AGS 4 release thread for download links:
https://www.adventuregamestudio.co.uk/forums/ags-engine-editor-releases/ags-4-0-early-alpha-for-public-test/
Demo game project:
https://www.dropbox.com/scl/fi/q8lwoi6xwg4m7apezs6i8/ags4-shaders.zip?rlkey=12d4gxmfln1dh4h1zh0e2vpfs&st=9wdbt6e4&dl=0
Compiled game:
https://www.dropbox.com/scl/fi/yj98k9o43tiuufbo180cq/ags4-shaders-game.zip?rlkey=yspxgpfzduspun7o6a6s8kq4l&st=xuewfvb4&dl=0

Example preview:
Spoiler

[close]



Explanation and instructions

The idea overall is this:

1. User writes custom shader scripts

Shaders are written in either GLSL (OpenGL shader language) or HLSL (Microsoft's shader language for Direct3D). These scripts are distributed along with the game, either as external files, or packaged using "Package custom folders" option in General Settings.

OpenGL graphics driver uses GLSL scripts and compiles them into shaders at runtime.
Direct3D graphics driver uses HLSL scripts and compiles them into shaders at runtime.
Optionally Direct3D can also load up precompiled shader objects (FXO). These may be created using Microsoft's "fxc" utility ("Effect-Compiler") from the older DirectX SDK (deprecated and archived), or possibly a modern equivalent "dxc" ("directx compiler"). Frankly, I haven't tested the latter yet, so not fully sure if it supports old HSLS dialect for Direct3D 9, which is used by AGS.



2. In script there are two new structs declared: ShaderProgram and ShaderInstance.

ShaderProgram represents a compiled shader, while ShaderInstance represents a shader setup: which is a shader + a set of custom shader values.
For those who have an idea of how modern game engines work: you may think of ShaderInstance as a kind of a very limited "Material" type.
ShaderProgram is used to create ShaderInstances, and ShaderInstances are assigned to the game objects.

Following may have a shader assigned:
* Screen.Shader
* Viewport.Shader (e.g. Screen.Viewport.Shader)
* Camera.Shader (e.g. Game.Camera.Shader)
* Object.Shader, Character.Shader, GUI.Shader, GUIControl.Shader, Overlay.Shader
* Room.BackgroundShader
* Mouse.CursorShader


The new structs are declared like:
Code: ags
builtin managed struct ShaderProgram {
  /// Creates a new ShaderProgram by either loading a precompiled shader, or reading source code and compiling one.
  import static ShaderProgram* CreateFromFile(const string filename); // $AUTOCOMPLETESTATICONLY$
  /// Creates a new shader instance of this shader program.
  import ShaderInstance* CreateInstance();
  /// Gets the default shader instance of this shader program.
  import readonly attribute ShaderInstance* Default;
};

builtin managed struct ShaderInstance {
  /// Sets a shader's constant value as 1 float
  import void SetConstantF(const string name, float value);
  /// Sets a shader's constant value as 2 floats
  import void SetConstantF2(const string name, float x, float y);
  /// Sets a shader's constant value as 3 floats
  import void SetConstantF3(const string name, float x, float y, float z);
  /// Sets a shader's constant value as 4 floats
  import void SetConstantF4(const string name, float x, float y, float z, float w);
  /// Sets a secondary shader's input texture, using a sprite number. Only indexes 1-3 are supported.
  import void SetTexture(int index, int sprite);

  /// Gets this instance's parent Shader
  import readonly attribute ShaderProgram* Shader;
};

You create a ShaderProgram using CreateFromFile static method. The filename you pass may contain a glsl, hlsl or fxo extension, but the engine will choose an actual file depending on the current graphics driver. For example, you call CreateFromFile("shaders/myshader.glsl"). If you run with OpenGL engine will look for "myshader.glsl". If you run with Direct3D engine will look for "myshader.fxo" (precompiled directx shader), and if it's not present, then for "myshader.hlsl" (directx shader source). This goes vice versa too. Such approach lets user pass the filename in any format, and not make extra if/else conditions in script checking current gfx driver (although you may if you need to).

ShaderProgram object is created always, even if shader compilation is failed for any reason. This is essential, because graphic driver may not support this shader, or not support shaders at all (such as Software graphics driver). This lets you write scripts not worrying about things failing if player switches to another driver. Of course the real visual effect will only appear if the actual shader was initialized successfully; otherwise this shader program will just do nothing.

After ShaderProgram is created, you have two options:
* use ShaderProgram.Default property which returns a always present default ShaderInstance. This instance is there to simplify things for you.
* create more ShaderInstances using ShaderProgram.CreateInstance() method.

Simple example would be like:
Code: ags
ShaderProgram* myshader;

function game_start()
{
    myshader = ShaderProgram.CreateFromFile("$DATA$/shaders/myshader.glsl");
    Screen.Shader = myshader.Default;
}

Why create more instances? Shaders may have "constants" in them, which may be thought as shader settings. These "constants" are not really constants in general sense, they are called "constants" because they don't change while shader is used in drawing. But you may change their values between the draws.
There are alot of purposes to use constants. Just to give couple of examples:
* a shader that tints a sprite by adding certain color - may have a constant "color", which you configure in script.
* a shader that changes the sprite look depending on time - then it will have a constant "current time", which engine will update each frame (find more info below).

So, suppose you have one shader, but want to configure this shader differently for different objects. That's where you need separate ShaderInstances.
You create 5 shader instances, and assign these to 5 objects, then set different constant values for these separate instances.

Here's an example:
Code: ags
ShaderProgram* myshader;
ShaderInstance* myshaderInsts[5];

function game_start()
{
    myshader = ShaderProgram.CreateFromFile("$DATA$/shaders/myshader.glsl");
    for (int i = 0; i < 5; i++)
    {
        myshaderInsts[i] = myshader.CreateInstance();
        object[i].Shader = myshaderInsts[i];
    }
    
    myshaderInsts[0].SetConstantF3("Color", 1.0, 0.0, 0.0); // red
    myshaderInsts[1].SetConstantF3("Color", 0.0, 1.0, 0.0); // green
    myshaderInsts[2].SetConstantF3("Color", 0.0, 0.0, 1.0); // blue
    // and so on
}



How to write shaders

In very primitive way "pixel shader" is an algorithm that is run over each pixel of a sprite, receives a real pixel color as an input, and returns same or another pixel color as an output. So what it does, essentially, is changing sprite pixel colors in some way. This change is not permanent (the sprite remains) but the result of a shader is used to draw this sprite on screen.

Unfortunately, I do not have enough expertise nor spare time to explain shader scripts from ground up. But AGS uses standard shader languages, and there must be thousands of tutorials online.

There are however few things that I must mention.

When writing shaders you may have your custom constants in it, but are also allowed to use a number of "standard" constants provided by the engine. The engine sets their values automatically for each draw so you don't have to do that yourself (in fact, if you do then these values will get overridden by the engine).
In GLSL these must match the name and type, but their order is not important (they may be not present if not used too). That's because OpenGL finds these by name.
In HLSL these constants EITHER must match the type and the *register number*, OR you have to write an accompanying ini file called "<shadername>.d3ddef", which describes your shader. That's because Direct3D 9 needs a different utility library for finding constant automatically, but this library is outdated, so I decided to not use it to be safe. I will explain "d3ddef" file a little further.

Following is the list of primary standard constants:
* float iTime - current time in seconds; note that it's not exact values that should matter, but the fact they it changes over time
* int iGameFrame - current game frame index (NOTE: must be float in HLSL, because apparently it D3D9-compatible mode does not support integer constants? at least that's what I read somewhere);
* sampler2D iTexture - sprite's texture reference;
* vec2 iTextureDim - texture's dimensions in pixels (type `float2` in HLSL);
* float iAlpha - sprite's general alpha (object's transparency);
* vec2 iOutputDim - final dimensions in pixels (type `float2` in HLSL); this constant is only set for the "whole screen shader" and tells the real resolution that the image will have when appear in window. If this shader will be applied to other game object, then this constant will have value of zero.

These are standard constants used to attach more textures to the shader:
 * sampler2D iTexture0 to iTexture3 (NOTE: iTexture0 is an alias to iTexture, and either of these two may be used);
* vec2 iTextureDim0 to iTextureDim3 (NOTE: iTextureDim0 is an alias to iTextureDim).

Other predefined input parameters:
* vec2 vTexCoord - is predefined for GLSL only, gets current texture coordinate for the pixel. HLSL should use TEXCOORD0 input parameter (see shader examples below).

Example of declaring parameters in GLSL:
Code: ags
uniform float iTime;
uniform int iGameFrame;
uniform sampler2D iTexture;
uniform vec2 iTextureDim;
uniform float iAlpha;

varying vec2 vTexCoord;

Example of declaring parameters in HLSL (notice the order of registers! - that matters if you precompile the shader):
Code: ags
// Pixel shader input structure
struct PS_INPUT
{
    float2 Texture    : TEXCOORD0;
};

// Pixel shader output structure
struct PS_OUTPUT
{
    float4 Color  : COLOR0;
};

sampler2D iTexture; // is in sampler register 0

const float  iTime:        register( c0 );
const float  iGameFrame:    register( c1 );
const float2 iTextureDim:  register( c2 );
const float  iAlpha:        register( c3 );



Example of my "Colorwave" shader in GLSL (for OpenGL):

Spoiler
Code: ags
uniform sampler2D iTexture;

uniform float iTime;
uniform int iGameFrame;
uniform vec2 iTextureDim;
uniform float iAlpha;

varying vec2 vTexCoord;

#define PI                 3.1415
#define PI2                6.283
#define FPS                120.0
#define WAVE_DIR          -1.0
#define TINT_STRENGTH      0.2
#define X_OFFSET_STRENGTH  0.00
#define Y_OFFSET_STRENGTH  0.02

void main()
{
    vec2 uv = vTexCoord;
    // convert from textcoord [-1;1] to [0;1] range
    vec2 uv_1 = uv * 0.5 + 0.5;
    // timer goes [0 -> 1) and resets, in FPS frequency
    float timer = mod(iGameFrame, FPS) / FPS;
    // wave cycles by timer + add starting phase depending on texture pixel position
    float wave_x = sin((WAVE_DIR * PI2 * timer) + (PI2 * uv_1.x));
    float wave_y = sin((WAVE_DIR * PI2 * timer) + (PI2 * uv_1.y));
    float wave_z = sin((WAVE_DIR * PI2 * timer) + (PI  * uv_1.x));
    
    vec3 tint = vec3(TINT_STRENGTH * wave_x, TINT_STRENGTH * wave_y, TINT_STRENGTH * wave_z);
    vec4 color = texture2D(iTexture, uv + vec2(wave_x * X_OFFSET_STRENGTH, wave_y * Y_OFFSET_STRENGTH));
    
    gl_FragColor = vec4(color.xyz + tint, color.w);
}
[close]

and same shader in HLSL (for Direct3D):

Spoiler
Code: ags
// Pixel shader input structure
struct PS_INPUT
{
    float2 Texture    : TEXCOORD0;
};

// Pixel shader output structure
struct PS_OUTPUT
{
    float4 Color  : COLOR0;
};

// Global variables
sampler2D iTexture;

const float  iTime:        register( c0 );
const float  iGameFrame:   register( c1 );
const float2 iTextureDim:  register( c2 );
const float  iAlpha:       register( c3 );

#define PI                 3.1415
#define PI2                6.283
#define FPS                120.0
#define WAVE_DIR          -1.0
#define TINT_STRENGTH      0.2
#define X_OFFSET_STRENGTH  0.00
#define Y_OFFSET_STRENGTH  0.02

PS_OUTPUT main( in PS_INPUT In )
{
    float2 uv = In.Texture;
    // convert from textcoord [-1;1] to [0;1] range
    float2 uv_1 = uv * 0.5 + 0.5;
    
    // timer goes [0 -> 1) and resets, in FPS frequency
    float timer = fmod(iGameFrame, FPS) / FPS;
    // wave cycles by timer + add starting phase depending on texture pixel position
    float wave_x = sin((WAVE_DIR * PI2 * timer) + (PI2 * uv_1.x));
    float wave_y = sin((WAVE_DIR * PI2 * timer) + (PI2 * uv_1.y));
    float wave_z = sin((WAVE_DIR * PI2 * timer) + (PI  * uv_1.x));
    
    float3 tint = float3(TINT_STRENGTH * wave_x, TINT_STRENGTH * wave_y, TINT_STRENGTH * wave_z);
    float4 color = tex2D(iTexture, uv + float2(wave_x * X_OFFSET_STRENGTH, wave_y * Y_OFFSET_STRENGTH));
    
    PS_OUTPUT Out;
    Out.Color = float4(color.xyz + tint, color.w);
    return Out;
}
[close]

Back to the "d3ddef" file required for the Direct3D's HLSL shaders. This file is obligatory if you have custom constants, as Direct3D cannot know about these. Another reason to write one if you like to specify compiler target (HLSL version).
"d3ddef" file is a simply "ini" file, which may contain few options:

Code: ags
[compiler]
target = compilation target ("ps_2_0", and so on)
entry = entry function name (e.g. "main")

[constants]
<constant_name> = register index (a number >= 0)

If "compiler" options are not present, Direct3D will use defaults.
If "constants" are not present, Direct3D will use default hardcoded register values. Note that if you write "[constants]" section in it, then you MUST mention ALL constants, including standard ones.

This may be an example of "colorwave.d3ddef" for my demo shader (I don't really use it in the demo game, but could have):
Code: ags
[compiler]
target = ps_2_b

[constants]
iGameFrame = 1
iTextureDim = 2
iAlpha = 3
#331
Quote from: Jleger91 on Fri 11/04/2025 16:30:57Entered this code under on_mouse_click() in globalScript.asc and it didn't work

Go to General Settings -> Inventory -> Override builtin inventory window click in script -> Enable.

But then you also will have to script other actions on inventory, such as using other verbs.

Code: ags
    if (button == eMouseLeftInv)
    {
        // if clicked using a "pointer" verb or other selected item,
        // then switch to a clicked item
        if (mouse.Mode == eModePointer || mouse.Mode == eModeUseInv)
        {
            mouse.Mode = eModeUseInv;
            player.ActiveInventory = inventory[game.inv_activated];
        }
        // if clicked using another verb (like "Look"), then run a corresponding interaction
        else
        {
            inventory[game.inv_activated].RunInteraction(mouse.Mode);
        }
    }


Also, keep in mind that if you do it this way, then you won't be able to use items on items.
#332
Quote from: Khris on Fri 11/04/2025 13:31:36Once you import a sprite, it ends up in a file called acsprset.spr and the external file is no longer needed. It can in theory be deleted. Room backgrounds are stored in the *.crm files.
Both sprites and room backgrounds can even be exported to the hard drive, should you lose the original image file.

Sorry, but getting rid of those image files is a very bad thing to suggest, and it's opposite to what we usually recommend. "acsprset.spr" is a huge binary file which may be subject to corruption if anything goes wrong when saving. It is also inconvenient to store under the source control (if you're using one, like svn or git or else). That's why the Editor has "recreate all sprites from sources" command, which restores "acsprset.spr" from the source image files. That's why we also recommend to put original image files into the game project's subfolder and import from there: this way Editor remembers their relative path and can restore the sprites even if the project was moved to another location or another computer.

Same thing with rooms. In AGS 3.* rooms are binary files, and if something breaks in them, they cannot be restored unless you have original backgrounds somewhere.

That said, you may of course move original images somewhere else. That will not break your game project. But if you would ever need to restore them in the project (if something breaks there, etc), then you would have to either:
- copy them back to where they were originally, and run restoration process;
- change the source links for all sprites to a new location (even on USB). There's a way to do this with a menu command in a upcoming version 3.6.2, but in earlier versions you would have to do a replacement in Game.agf file (that's a xml text).

#333
I suggest replacing the drawing part with a classic 2 nested for loops, running along Y and X axis:

Code: ags
for (int y = 0; y < Room.Height; y += Game.Camera.Height)
{
    for (int x = 0; x < Room.Width; x += Game.Camera.Width)
    {
        Game.Camera.SetAt(x, y);
        Wait(1);
        PartialScreenShot = DynamicSprite.CreateFromScreenShot();
        DrawOntoBig.DrawImage(Game.Camera.X, Game.Camera.Y, PartialScreenShot.Graphic);
    }
}

This may replace all the code after line
"DynamicSprite* BigScreenShot = DynamicSprite.Create(Room.Width, Room.Height);"
up to line
"DrawOntoBig.Release();"

But still there's a case when the room is not evenly divided by camera size. AGS will clamp the camera position in such case, meaning that the code might draw only part of the screenshot for the edge parts in sake of being optimal.
NOTE: this is only a problem with code doing extra work, so may be ignored.
Spoiler
I think the DrawImage code should then be something like this (but did not test it yet):
Code: ags
    // Set up offsets in case room size is not evenly divided by camera size,
    // and camera position was adjusted by the engine for the edge tile
    int xdiff = x - Game.Camera.X;
    int ydiff = y - Game.Camera.Y;
    DrawOntoBig.DrawImage(x, y, PartialScreenShot.Graphic, 0,
            PartialScreenShot.Width - xdiff, PartialScreenShot.Height - ydiff,
            xdiff, ydiff, PartialScreenShot.Width - xdiff, PartialScreenShot.Height - ydiff);
[close]
#334
First of all, you need to clarify few things:
1. Which template do you use, or, if you have started from empty template, then how does your gui look like and what script do you have for inventory.
2. How exactly do you want it to work.

I am not fully certain if this is what you're asking, but if you really want to swap a selected item when player clicks on another item, then it's done in on_mouse_click where you handle eMouseLeftInv. In a common case it would look something like this:

Code: ags
function on_mouse_click(MouseButton button)
{
   ..... some code here

    // this means - left mouse click on some inventory item
    if (button == eMouseLeftInv)
    {
        // select a new item regardless of whether one is already selected or not
        player.ActiveInventory = inventory[game.inv_activated];
    }
}

But before applying this code you need to double check which inventory controls do you already have in script.
#335
If you have a separate room for the title screen, then you may instead test for the current room. The current room is the one where "player" character is:

Code: ags
if (keycode == eKeyEscape && player.Room != NUMBER_OF_TITLE_SCREEN_ROOM)
#336
Quote from: Baguettator on Tue 08/04/2025 20:18:51Is it "I don't need" or "I must not" declare get_ and set_functions in the struct ?

You "don't need", but may.

Note that "set_" functions must have a "new value" as an argument, otherwise they won't compile properly. I.e.
Code: ags
import void set_Mort(int new_mort);

But I missed what you say about "don't want anything able to modify this attribute directly". In such case you should declare your attribute as "readonly", and "set" function should not be present at all.

Code: ags
import readonly attribute bool Mort;
#337
Quote from: Baguettator on Tue 08/04/2025 16:19:05I have no problem with v3 compiler. Is it a bug ?

v3 compiler lets numerous syntax mistakes pass where it should report error. v4 compiler is more strict.

set_ functions of attributes must be "void", because they set and not return. You have other set_ functions as void above, except set_Mort.

Also, you do not need to declare get_ and set_ functions in the struct, attribute declaration is enough.
#338
Quote from: Baguettator on Tue 08/04/2025 06:21:38Hi !

I'm trying the new multidimmensionnal arrays system, but I encounter an error when building the game.

Please double check that you are using the new script compiler, it's selected in General Settings -> Compiler -> Script compiler.
#339
Hello. If you are using a built-in score feature (with GiveScore command), then engine will call "on_event" script function for it, with eEventGotScore parameter:
https://adventuregamestudio.github.io/ags-manual/Globalfunctions_Event.html#on_event

The code would look something like:
Code: ags
function on_event(EventType event, int data)
{
    if (event == eEventGotScore)
    {
         if (game.score == 10)
         {
              player.AddInventory(item);
         }
    }
}


On the other hand, if you are not using a built-in score feature, but have your own score variable, then you should write your own function which adds score and checks for certain score level.
SMF spam blocked by CleanTalk