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

Topics - Crimson Wizard

#141
AGS 3.5.0 - Alpha 13

Download 3.5.0 (Alpha 13) as a .zip archive
Download Dark UI Theme for the editor


ACHTUNG!
This is a development version of AGS 3.5.0.
Use at your own risk. Please back up any games before opening them in this version of AGS.
New settings in this version may make your project files unusable in previous versions after saving with this version.

Last updated: 17th of April, 2019
Has all content from AGS 3.4.3.1.

NOTE: this version was previously known as 3.4.2, but we decided to rename it to 3.5.0 to indicate the significance of some changes.


This release is brought to you by:

- Alan v. Drake
- BigMC (fixes to building on some Linux systems)
- ChamberOfFear
- Crimson Wizard
- John Steele Scott (OpenGL support on Linux)
- Martin Sedlak (new pathfinding)
- Matthew Gambrell (better threaded audio support and bug fixes)
- morganw
- rofl0r
- scottchiefbaker (fixes to building on some Linux systems)
- sonneveld
- tzachs (new navigation bar for the Room Editor)



What is new in 3.5.0

Common features:
- Support for large files: compiled game, sprite set, room files now may exceed 2 GB.
- Deprecated relative assets resolutions: now sprites, rooms and fonts are considered to match game's resolution by default and not resized, unless running in backwards-compatibility mode.
- Allow room size to be smaller than the game's resolution.
- Removed fonts count limit.
- Raised imported sprites count limit to 90000 and removed total sprite count limit (this means you may have around 2 billions of dynamic sprites).
- Removed length limit on the Button and TextBox text.

Editor:
- Editor requires .NET Framework 4.5 to run. Dropped Windows XP support.
- Editor preferences are now stored using .NET configuration model, instead of the Windows registry.
- Added support for custom UI color themes.
- Game and room templates are now by default saved in AppData/Local/AGS folder. Editor finds them in both program folder and AppData.
- Added "Allow relative asset resolutions" option to "Backwards Compatibility" section. Disabled by default, it makes game treat all sprites and rooms resolution as real one.
- New revamped sprite import window.
- Sprites that were created using tiled import can now be properly reimported from source.
- Added context menu command to open sprite's source file location.
- Using Magick.NET library as a GIF loader. This should fix faulty GIF imports.
- New sprite export dialog that lets you configure some export preferences, including remapping sprite source paths.
- Sprites have "Real" resolution type by default. "Low" and "High resolution" are kept for backwards compatibility only. When importing older games resolution type will be promoted to "Real" whenever it matches the game.
- New navigation bar in the room editor, which allows to select any room object or region for editing, show/hide and lock room objects and regions in any combination.
   These settings are saved in the special roomXXX.crm.user files.
- Improved how Room zoom slider works, now supports downscale.
- Added "Export mask to file" tool button to the Room Editor.
- Added MaskResolution property to Rooms. It ranges from 1:1 to 1:4 and lets you define the precision of Hotspot, Regions and Walkable Areas relative to room background.
- Added "Default room mask resolution" to General Settings, which value will be applied
   to any room opened for editing in this game for the first time.
- Removed Locked property from the Room Object, objects are now locked by the navbar.
- Split GUI's Visibility property into PopupStyle and Visible properties.
- Added Clickable, Enabled and Visible properties to GUI Controls.
- "Import over font" command now supports importing WFN fonts too.
- Removed "Fonts designed for high resolution" option from General Settings. Instead added individual SizeMultiplier property to Fonts.
- Display audio clip length on the preview pane without starting playback.
- Added "Always"choice to "Popup message on compile" preference. Successful compilation popup will only be displayed if "Always" choice is selected.
- Added shortcut key combination (Shift + F5) for stopping a game's debug run.
- Don't display missing games in the "recent games" list.
- Build autocomplete table a little faster.
- Corrected .NET version query for the anonymous statistics report.
- Fixed sprite folders collapsing after assigning sprite to a View frame or an object.
- Fixed view loops displayed with offset if the view panel area was scrolled horizontally prior to their creation.
- Fixed Audio folders were displaying internal "AllItemsFlat" property on property grid.
- Fixed MIDI audio preview was resetting all instruments to default (piano) after pausing and resuming playback.
- Fixed MIDI audio preview had wrong control states set when pausing a playback.
- Fixed script compiler could leave extra padding inside the compiled scripts filled with random garbage if script strings contained escaped sequences like "\n" (this was not good for source control).
- Fixed crash when editor was updating file version in compiled EXE but failed and tried to report about that.

Script API:
- Introduced new managed struct Point describing (x,y) coordinates.
- Implemented Dictionary and Set script classes supporting storage and lookup of strings and key/value pairs in sorted or unsorted way.
- Implemented Viewport and Camera script classes which control how room is displayed on screen.
- Implemented Screen struct with a number of static functions and properties, which notably features a reference to the primary Viewport. Deprecated System's ScreenWidth, ScreenHeight, ViewportWidth and ViewportHeight in favor of Screen's properties.
- Added Room.Camera property that references primary room camera.
- All functions that find room objects under screen coordinates are now being clipped by the viewport (fail if there's no room viewport at these coordinates).
   This refers to: GetLocationName, GetLocationType, IsInteractionAvailable, Room.ProcessClick, GetWalkableAreaAt and all of the GetAtScreenXY functions (and corresponding deprecated functions).
- Added Character.GetAtRoomXY, Hotspot.GetAtRoomXY, Object.GetAtRoomXY, Region.GetAtScreenXY, replaced GetWalkableAreaAt with GetWalkableAreaAtScreen and added GetWalkableAreaAtRoom.
- Replaced Alignment enum with a new one which has eight values from TopLeft to BottomRight.
- Renamed old Alignment enum to HorizontalAlignment, intended for parameters that are only allowed to be Left, Center or Right.
- Added new script class TextWindowGUI, which extends GUI class and is meant to access text-window specific properties: TextColor and TextPadding.
- Added new properties to GUI class: AsTextWindow (readonly), BackgroundColor, BorderColor, PopupStyle (readonly), PopupYPos.
- Added Button.TextAlignment and Label.TextAlignment.
- Added missing properties for ListBox: SelectedBackColor, SelectedTextColor, TextAlignment, TextColor.
- Replaced ListBox.HideBorder and HideArrows with ShowBorder and ShowArrows.
- Added TextBox.ShowBorder.
- Added Game.PlayVoiceClip() for playing non-blocking voice.
- Added SkipCutscene() and eSkipScriptOnly cutscene mode.
- Deprecated DrawingSurface.UseHighResCoordinates. Also, assigning it will be ignored if game's "Allow relative asset resolutions" option is disabled.

Engine:
- New pathfinder based on the A* jump point search.
- Implemented new savegame format. Much cleaner than the old one, and easier to extend, it should also reduce the size of the save files.
   The engine is still capable of loading older saves, temporarily.
- Implemented support for sprite batch transformations.
- Implemented custom room viewport and camera.
- Removed 200 chars limit for DoOnceOnly token length.
- Reimplemented threaded audio, should now work correctly on all platforms.
- Improved performance of hardware-accelerated renderers by not preparing a stage bitmap for plugins unless any plugin hooked for the particular drawing events.
- Reimplemented FRead and FWrite plugin API functions, should now work in 64-bit mode too.
- Made fps display more stable and timing correct when framerate is maxed out for test purposes.
- Completely removed old and unsupported record/replay functionality.
- Replaced number of fatal errors reported for incorrectly called script functions with a warning to the warnings.log instead. This is done either when arguments may be fixed automatically, or script command simply cannot be executed under current circumstances.
- Expanded some of the error messages providing more information to end-user and developers.
- Fixed engine could not locate game data if relative path was passed in command line.
- Fixed potential bug which could cause DoOnceOnly tokens to be read incorrectly from a savedgame.
- Fixed DynamicSprite.SaveToFile() not appending ".bmp" if no extension was specified.
- Fixed IsMusicVoxAvailable() not working correctly in old games which use 'music.vox'.
- Fixed a bug in mp3/ogg decoder where it assumed creating an audiostream succeeded without actually testing one.
- Added Scavenger's palgorithms plugin to the list of builtins, for ports that use ones.

Linux:
- Support for OpenGL renderer.
- Use same FreeType library sources as Windows version, which suppose to fix TTF font glitches.
- Re-enabled threaded audio setting.
- Improved CPU yield function, this supposedly may reduce CPU usage.

Windows:
- Windows version of AGS is now built with MSVS 2015 and higher.


KNOWN ISSUES:

- Reported by Snarky: need to find out which components need to be added to use AGS 3.5.0 on fresh Windows installation.
- Some weird sprite scaling bug in the room editor described in the posts below. According to user reports it may be fixed by restarting the editor. Unfortunately I was still unable to reproduce it on my own...
- Custom Viewport and Camera properties are not remembered in savegame. Temporary workaround is to save these in variables and restore custom camera in eEventRestoreGame event.
And of course the ones noted at github issue tracker: https://github.com/adventuregamestudio/ags/issues?q=is%3Aissue+is%3Aopen+label%3Abug



On color themes

After launching the Editor, go to File - Preferences. In the "Editor Appearance" group box you will find "Color Theme" setting. If you haven't installed any themes yet the selection list will be empty. Press "Import Color Theme" and select appropriate JSON file, containing theme configuration.
Sample color theme: Dark UI Theme.

There is no specification on theme creation yet, but I hope there will be one at some point. For now you may copy and modify existing one. Themes are in JSON format, which you may edit in most simple text editors. If the theme is broken, the editor will report an error and reset to Default theme on startup.
ChamberOfFear also suggested creating a repository for the themes to let people upload their own and improve existing ones, which we may do in a future.



On new navigation bar in the room editor

This was made by tzachs back in 2014, but got into the editor only now. The feature is working, but may need polishing.

Screenshots (warning - big size):
Spoiler




[close]

Quoting tzachs (from his old thread) -

- Room Layers

This feature allows you to view (and edit) walkable areas/walk-behinds/hotspots/regions/characters/objects/edges in the same time (as opposed to only seeing one of them at a time, like we've seen before).
Well, not entirely though: walkable areas/walk-behinds/hotspots/regions still can't be seen together (as they use masks and is part of the natives dll so I skipped it for now) but they can be seen along objects, characters, and edges.

- Visibility

Each layer can be made visible/hidden by the push of a button. In addition, for the objects/characters/edges layers each item in the layer can also be made visible/hidden by the push of a button. This will only affect the editor, not the actual game.

- Locking

Each layer can be locked/unlocked by the push of a button. In addition, for each layer, each item in the layer can also be locked/unlocked by the push of a button.
A locked item cannot be moved until it is unlocked, useful to prevent mistakes when designing the room. This will only affect the editor, not the actual game.



On new room viewport and camera commands

This release changes the way AGS handles room viewport. Originally room view was covering whole screen and always drawn 1:1. 3.5.0 separates old viewport into viewport and camera, also changing the meaning of viewport term.

In 3.5.0:
Viewport is a place on screen where room is drawn, defined in game coordinates (e.g. 0,0 - 320x200).
Camera is a place in room which is being drawn, defined in room coordinates

The part of the room "seen" by camera is being copied to the viewport on screen, scaled up or down if necessary.
For example, if you set camera's size twice as small than the viewport, then room will appear zoomed in x2. If you set camera's size twice as big than the viewport, room will appear zoomed out x2.
NOTE: you cannot set camera size larger than the room's background.

To access viewport and camera use new properties: Screen.Viewport and Room.Camera.
Screen.AutoSizeViewportOnLoad boolean value turns automatic viewport adjustment on room load. It is ON by default which corresponds to normal room view you are used to.

Since the relation between screen and room is now more complicated new functions were added to help convert between screen and room coordinates: Screen.ScreenToRoomPoint(), Viewport.ScreenToRoomPoint() and Viewport.RoomToScreenPoint(). These functions return an object of Point type containing (x,y) coordinates.
Screen.ScreenToRoomPoint() returns null if there is no Viewport on screen under these coordinates. This is because if there will be multiple viewports supported in the future then engine simply won't know which to choose having none under these coords.
Both Viewport.ScreenToRoomPoint() and Viewport.RoomToScreenPoint() have 'clipViewport' parameter which tells whether they should return null if the coordinates lie outside of the visible part of the room.


Old viewport functions are now deprecated, they may still be enabled if you set "Script compatibility level" to v3.4.1 or lower.
Here's correspondence between old and new functions:




Old commandNew commad(s)
SetViewport(x, y);Room.Camera.SetAt(x, y);
ReleaseViewport();Room.Camera.AutoTracking = true;
GetViewportX();Room.Camera.X;
GetViewportY();Room.Camera.Y;

As you may see, what was known as "viewport" earlier is now called "camera", and "new viewport" is something that was never supported before.


On savegame format

AGS 3.5.0 introduces new savegame format. This had to be done for several reasons, mostly internal ones, because existing format was too difficult to maintain and expand.
From the user's perspective, the notable change is that save file will be somewhat smaller, because redundant data is no longer written there (I did some tests in the past, and iirc depending on circumstances the size reduction was about 20-40%, but this awaits confirmation).

The new format is completely non-compatible with the old one. This means that if you run some existing game with the new engine, and save a game, that save can't be loaded by previous engine.
On the other hand, new engine can still load old saves. Old saves support is temporarily and may be removed in future.
Keep these two points in mind if you plan on upgrading existing game to AGS 3.5.0.
#142
The file access rules - is something that still bothers me in AGS, and I'd really wish to patch it as one of my last ammendments to the engine.

It all started when Radiant asked me to save config file in the user documents instead of current folder, because it does not work when the game is installed in C:/Program Files (or any other non-writeable location). Instead of doing just that I also decided to change how file access works in game scripts too, but I have doubts that did that fully right.
I would like to make final fixes to that, and decided to post here to get any input from other people and make sure I don't screw that up again.


Summing up current state of the file system (as of 3.4.1):
1) When working with file system in scripts (opening files, loading sprites, and so on), following tokens may be used to define location:
* $INSTALLDIR$ - a directory where game was installed.
* $SAVEGAMEDIR$ - a directory for savedgames, one for each system user.
* $APPDATADIR$ - a directory for storing shared data, same for all system users.


2) The rules for working with files are following:
* Absolute paths are forbidden.
* When using $INSTALLDIR$ you cannot write anything, only read existing files.
* Game config lets you set up custom paths for $SAVEGAMEDIR$ and $APPDATADIR$. This is done primarily to let players change save game location according to their preference.
* When no location token is given, engine remaps the path as relative to $APPDATADIR$. Note, that this is different from how it worked before AGS 3.3.5, where path without token meant "relative to game's (installation) directory".
* Now, there is something not very explicit, which was made primarily for backward compatibility: when you are trying to read file using relative path without token, the engine will check two paths: first in $APPDATADIR$, then in $INSTALLDIR$. If a file is found in $APPDATADIR$, then it will be read, otherwise file in $INSTALLDIR$ (if it exists).
The reason for doing this was to silently remap relative paths in scripts in old games to $APPDATADIR$ when they are writing files, but still let them be able to read existing files from the current directory.
But this solution is something I am not very proud of...



The problems, as I see them, are:

1) Is it really good to completely deny writing to the current game directory? Initially I thought it is, since contemporary operating systems have stricter rules to where programs may write files. So this acts as a safety measure to prevent unexperienced game creators from making a mistake (as being said, game may fail if it tries to write to C:/Program Files/...).
On the other hand I myself found at least one case when that may be useful: if you are creating an edit mode inside your game, which creates data for the game itself.
Currently the only way to do that would be to setup custom path for $APPDATADIR$ for the development time and then do not forget to reset it to default before public release.
There is now a token with explicit meaning ($INSTALLDIR$), for which we may have a warning in the manual, telling not to write files there without serious reasons.

2) What should be the way to treat paths without a token? The idea behind changing from treating them as relative of game dir to relative of $APPDATADIR$ is that new users won't make their games impossible to be run from C:/Program Files by mistake. Is it a good reasoning? Because while it may make things safer it also may cause confusion
when user will look for the written files in the game directory and won't find them.

3) Not much related to running new games, but in terms of backward compatibility, is there a better solution for their issue? I am speaking of a situation when the game writes files to game directory, which makes it impossible to be install in particular locations.



The possible solutions I am thinking about right now are:

1) Allow to write files in $INSTALLDIR$. There are options here: make it work always or only if game works in Debug mode, if that makes sense.

2) I don't have a decisive opinion about how to deal with paths without tags.

3) I would like to try implementing different solution for older games. To remind, the problem is this: consider there is a game made a while ago where game author has used paths without token to save files to the game directory. You won't be able to use such game if it's installed somewhere where you cannot write (restricted directories, read-only device). One solution in such case is to simply install it somewhere else. But if that's unwanted or impossible for any reason, may there be a simple fix for this situation?
Right now, as I said, engine silently remaps writing file to $APPDATADIR$, but when reading it has to check both $APPDATADIR$ and $INSTALLDIR$.
Of course this is not ideal, because user may not find files where he expected to. This may be particulary annoying with games which include level editor, like old "ColorWise" game, for instance, where original levels are stored in the game directory, and player will probably expect to find all levels in one place.
So, I was thinking, what if instead of silently changing the path, it would use another option in config. The meaning of option would be "how to treat paths without token", and has possible values corresponding to supported path tokens. Such option could be used like a casual hack: if you've found an old game (or a newer game where author did not consider possible issues) that writes files to the game directory, and that causes trouble for you, you just set this option to something else, like $APPDATADIR$. (Naturally, at same time you may also set custom path for $APPDATADIR$).

BTW, if such option is introduced that may also change the opinion on p. 2), and perhaps paths without tags could mean $INSTALLDIR$ again. Idk about that.



#143
AGS 3.4.1 - Patch 1 released
Current release number: 3.4.1.12





Released: 28th January 2018

Previous stable version: AGS 3.4.0 forum thread


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)



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)

- Need to make mobile ports (Android, iOS) work 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.
NOTE: 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.
#144
Hello.

First of all, this is NOT another "feature request" topic.
This is also NOT "what to add to the next version of AGS" topic.


Sorry for this disclaimer. Please read further :).




There are few new engines underway, being made by people known in AGS community, such as XAGE, MonoAGS, and maybe some others we do not know about. They may copy AGS to some degree or reimagine adventure creating tool in their own way. Since I am currently considering contributing to one of them, and just because I think that might be important for any such undertaking, I would like to make a following survey.

The primary targets for this survey are people who have big experience working with AGS, but others may participate too, of course.

Survey has only two simple questions, but they may need extensive answers:
1) What do you like about AGS, and would like to keep if any new creative tool arrives?
2) What do you think should be changed (added, removed, altered)?

Now, this is NOT about simple and obvious things, like
- not being able to change GUI color at runtime, or
- having a limit of N sprites, or
- running on many platforms, etc

but rather about ones, such as
* editing workflow,
* methods to achieve something you want,
* script API design
(how well does script allow you to control game behavior), and so forth.

If you have experience working with other game creating systems, and may make a comparison, please do so.

I know that similar discussions were held in the past, but that may be hard to find these posts, so I wanted to make something "centralized" for this time. But links to old forum threads are also accepted.
#145
Hello.

I would like to tell about one idea that interests me. I had it for quite a long time in a form of random thoughts, but recently decided to go and try implementing this even if in a limited form, for starters.

This idea is of procedurically generated detective adventure game.

There was a pretty good number of procedural games in the past, so I guess everyone can imagine what is it in general. I've also seen procedural detective games before. Although I must admit that haven't played much of them, so cannot know many details, but the ones I've seen were mainly based on randomization of predefined roles and scenarios. While that may work perfectly for the game, my intention was to go further (or deeper), and instead of randomly granting every character a role (killer, victim, thief, witness, etc), grant them conflicting personalities and ambitions, that may randomly result in committing a crime under "fortunate" circumstances.

As such this is not only a game project, but also a research project about building a character AI. Or maybe even "story AI".

If you think above is a bit vague, let me give an example.

Imagine there is a mansion full of party guests. Each guest has particular personality traits and wishes assigned at the game's generation. Guests are wandering around the house, following certain rules (like avoiding restricted areas).
Consider one of the guests have a "cleptomaniac" personality, or maybe there is "financial problems" issue troubling them. This character enters a room with some "expensive item" on the showcase. A combination of character's traits and aims gives them a motive to steal the item. They wait for the right moment and do that. This is how the crime takes place.

The peculiarity of this approach that intrigues me much - is that since there are no predefined roles, not only player does not know who the criminal is, but even the game does not "know" that, until crime happened. In fact, there is always a theoretical possibility that more than one crime may take place (with different motives and participants), and maybe even sequences of events following first crime help another one to occur.

As with any AI, it is a matter to programmatically depict decision making. This game would require explaining such things through the code, as the concept of crime itself, clues, motives, ambitions and aims, personality traits and conflicts, and on advanced level - planning a strategy through assuming sequential events, manipulating other people, and so forth.


Obviously such approach also makes it harder to create a flawless scenario, but the challenge is perhaps the interesting part here.
The final goal of this potential project is to create AI that would be flexible and smart enough to generate an interesting game.
#146
Following are the reasons why this project was screwed up from the very beginning. Just for the sake of history. I'd like to believe this may help someone to avoid same mistakes, but people seem to rarely learn on their own, so IDK.

Actually, I cannot think of anything that was made right here, from the first steps every mistake that could be made was made.


1. The problem with AGS was the reliance on old library that was already badly working on contemporary systems in 2012. Instead of immediately moving to better up-to-date library (SDL2 or Allegro5), or framework (like ScummVM) the old library was patched to somehow work on wanted platforms.
Usually the patching was performed by a single person. After such person took their leave, little information remained about their work, and whenever any kind of issue arised with the port, it took a lot of effort to figure out what to do.
Often the library was patched having only one particular port in mind. Sometimes a functionality was added right into this patch, different from the rest of the engine, causing inconsistences.

A lot of additional work related to device controls and graphic modes could be omitted, if we could rely on modern library. For example, I had to rewrite graphics renderers 5 or 6 times adding better display mode selection over those years.

The result: AGS is still based on same old library that work worse and worse on contemporary systems.


2. The problem of AGS was that Windows version was glued to particular old version of MSVS, which was even non-free. Instead of immediately looking for a way to remove that dependency, we kept it for several years.

Result: many potential contributors could not contribute because they could not even build it.


3. The problem with AGS was bad program code. Instead of immediately refactor it from top to bottom, this was only partially complete before we switched to compatibility fixes, and then - adding new functionality. Because of that a lot of time was wasted trying to hack new stuff into existing code. Supposedly, the bad code also scared away other potential contributors.

Additional moment: there was already a refactored code made by ScummVM developer, licensed under same license as AGS, which could be used, even if partially. But it was never used.

The result: AGS still has got a lot of non-refactored code which is barely known, and many features or fixes that were very wanted were never added because of that.


4. The problem with AGS was that the engine and editor contained a lot of legacy support that was practically useless for making game in current day, but cluttered up the code and made it difficult to develop it further.

Instead of splitting out legacy support into separate branch, we not only kept it in the engine, but increased its amount by adding support for even older games.
Because of this, adding any new feature required a lot of extra time, necessity to test whether ancient games still run with this engine after every update. This additionally mixed up with the non-refactored code producing more mess.

It may be hard to fully recognize consequences of this decision. A lot of system limits are there only because of legacy support and old plugin API support. There was a time when I spent over half of a year trying to remove these limits while keeping the legacy support, but in the end just threw the code out, so ugly it was.
Similarily, a lot of features could not be easily added simply because there was some fragile legacy stuff that could break.


Result: amount of time just wasted for nothing is impossible to calculate. Neither it is possible to know how much we could have done more if not for this.
Number of potential collaborators probably did not want to participate in project because of confusing code.


5. The problem with AGS was that with very little number of collaborators nevertheless we sometimes wasted time on something that could have been avoided. It was in our interests to take easier routes requiring less job where possible. Instead, the project started with one developer willing to write a class library specifically for AGS instead of using standard one. Another developer kept waiting several months for those classes, purposedly trying to avoid adding standard ones into engine. When it became clear that there will be none, instead of immediately switching to standard library, that second developer, for the reasons he cannot even explain today, decided to follow suggested idea and write these classes himself. In the end he did, kind of, but then realized that with them he will be drawned into maintaining utility classes instead of working on engine itself, so, again, just threw the code away. So, now we do use standard library, but nearly two years were lost.

This is only one such example. I could probably remember other not so useful stuff that I wasted time on, because someone said (in the end many things I did were not even added to the release).


6. The problem with AGS was the lack of automation. Everything had to be made manually. No automatic builds, let alone tests, nothing. If a person wanted to suggest features or changes, developers had to manually build and test their version to just make sure it compiles.
There was no way to know if all ports are still working or were broken by some of the recent additions except for building them all or waiting when someone tries to. And not everyone could build all the ports, naturally.
Making a full release package with all the data - demo game, templates, etc, - became such ordeal, that frankly, I tried to delay release every time until more changes accumulate, simply because I did not want to go through all this too often.


7. The problem with AGS was terrible organization. This was a project without actual leadership nor vision. There was no development plan, no documentation. Everyone just did some stuff as they see fit.
There was very little communication between game developers and AGS developers. With lots of ideas it was difficult to filter out things that were actually important to many people. A lot of critical nuances stayed unknown until occasionally mentioned years later.
A lot of tasks, even mentioned on forums, were never solved, even though several people could state their interest in that. Good example is this thread:
http://www.adventuregamestudio.co.uk/forums/index.php?topic=51340.0
Just look at this:
Spoiler

Quote from: Monsieur OUXX on Sat 29/11/2014 01:38:02
The help file is getting more and more out of sync with the actual Editor. <...>
The issue with the help file is that it's generated from some old LaTeX dialect, which in turn creates an old-school Windows help file (.chm files). <...>
We need to find a solution.
Quote from: sonneveld on Sun 03/07/2016 10:50:47
I can help.
Quote from: eri0o on Fri 21/07/2017 23:34:23
I used to use pandoc and sphinx, I was passing on the AGS topics and this is the first thing I thought "I know how to automate this!"
<...>
Can someone point me the source files?
[close]
From 2014 to 2018, and it did not move anywhere. Meanwhile, this is not even related to engine code or C++.

If organization were better, perhaps a number of other problems not directly related to coding engine could have been solved. (e.g. this: http://www.adventuregamestudio.co.uk/forums/index.php?topic=55646.0)
Simply because people could notice that such task exists.
#147
This is long overdue, but recently my attention was brought again to this old post from 2014 (I think it is by one of the creators of Primordia):
http://www.rpgcodex.net/forums/index.php?threads/primordia-a-point-and-click-adventure-now-available.49740/page-22#post-3135923

It is nearly 2018 now, but all those issues still exist.

I answered this on gtihub back few years ago, but I guess no one noticed. Perhaps I should've try harder and post here, but, to be honest, don't remember if any game dev has ever asked me about this.

Anyway...



There is this command-line tool pack made by github user rofl0r back in 2012-13: https://github.com/rofl0r/agsutils

Among other things they can unpack and repack AGS game file.
A small caveat - they only known to compile under Linux, so probably might need be updated to compile under Windows too.

The solution to game patching is as following:
1. Provide a patch script and patch contents (e.g. in ZIP archive).
2. Patch script (written in any common scripting language, heck even batch for Windows system) -
2a. unpacks patch archive to folder P.
2b. runs unpacker tool to extract game data to folder G.
2c. copies patch files from P to G.
2d. runs packer tool to recreate game file with the new files of folder G.
2e. deletes temporary files.
3. Profit: you have a game exe with new contents.


EDIT: right, how to create patch in the first place:
a. You need to have two game files: old and new one.
b. Unpack both into folders O and N.
c. Compare the contents and find the files in N that do not match O.
d. Create a ZIP archive that onlu contains changed files.


This may be further improved by writing a simple GUI wrapper over those utilities.


Limitations:
Of course with current AGS package system you won't be able to replace certain items without replacing larger chunk. Sprites is the main problem here, because even inside game package they are stored as another monolithic file (sprcache.dat). Another thing is script modules: they are merged together with main game data (game, character, inventory descriptions, etc). Room files (CRM) have both room background, properties and scripts merged altogether. This is indeed something you cannot change without rewriting way AGS handles these.
#148
Quote from: morganw on Mon 25/12/2017 15:39:36Personally I would like to think there was an opportunity to have a continually developed runtime using the SCUMMVM backend, that does not maintain backwards compatibility and can have a few more contemporary features.
This is one of the possibilities. I had big doubts in the past, particularily because they did not have hardware-accelerated gfx support, which I'd like to have in AGS. But now they seem to have it, or so I heard.

There may actually be two variants here:
- develop AGS runtime as a part of their framework;
- only take their backends system and develop runtime separately (if that's technically and legally possible).

But I guess this all is a separate topic. [Done! â€"Snarky]
#149
Sorry, that is kind of weird, what started very recently when I click on some forum links in posts leading to old threads (from 2011 - 2012), Google Chrome shows that red danger screen, and sais that -
"www. shuugouteki. net" is a dangerous site that may install malicious software. I have no idea what this site even is, because link clearly is pointing to http://www.adventuregamestudio.co.uk/forums/***.

Going onto these threads step by step from the main forum page works well nevertheless.

What may this be?
#150
AGS Engine & Editor Releases / AGS 3.4.1
Sat 23/12/2017 20:49:22
AGS 3.4.1 released
Current release number: 3.4.1.11





Released: 23th December 2017

Previous stable version: AGS 3.4.0 forum thread


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)


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)

- Need to make mobile ports (Android, iOS) work 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.
NOTE: 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.
#151
DOWNLOAD Timer 0.9.0 MODULE

Latest source code may be found here
Git cloning address: https://ivan-mogilko@bitbucket.org/ivan-mogilko/ags-script-modules.git

Module supports AGS 3.4.0 and higher


Other script modules by me:
Spoiler



Quick pre-word

Few months back I urgently needed a Timer module with certain functionality, and was hoping to download monkey0506's Timer module, but official links were broken (later I found the only working link, but it lead to an old version). So I wrote my own alternate variant, and posted an initial code in the same thread.

I made certain decisions, such as creating a managed class which you have to operate through pointers, that may cause controversy (this clearly has both advantages and disadvantages).  Even now I keep having doubts about that. In theory it could be possible to remake it into non-managed class if people will find this not convenient (although there may be complications related to AGS scripting limits).
I also do not know whether monkey0506 had any plans on his own module; I would not mind even merging our modules at some point.


Introduction

The Timer module addresses an issue of built-in timers in AGS: that may be difficult to ensure that you do not reuse same timer for different purpose.
Spoiler

In AGS timers are identified with numbers; this is not a problem on its own, because you can always declare a named constant with #define (like "#define TIMER_BOMB 1") and use that instead. What is the problem, that these IDs are all sharing same "namespace". Basically, you are not creating your own timers, you are reusing same ones from the single list of timer "slots". And there is little way to guarantee that you do not start timer N in another place while the previously created timer N is still running. This requires coder's discipline and planning, but in the big project may become tedious. Additionally, that complicates using timers in the modules and templates (module writer would have to let people customize timer ID's to make sure they don't conflict with anything in game).
[close]

Timer class solves this issue, because you are no longer forced to use same available X timers from the list, but can create any number of Timer variables.

For AGS-related technical reasons there is however a limitation: only finite number of timers may be run at the same time. This number is 20 by default, but may be changed at will.
Spoiler
The real problem in AGS is that it's impossible to call repeatedly_execute function explicitly for the managed object, we have to use global repeatedly_execute and call object updates from there. Which in turn means that the module must keep references to active timers in an array.
Of course I could implement self-resizing array, but thought that timers are not kind of things that might need such effort. This still may be done in a future update though.
[close]

Timer is implemented as a managed class, which means that you need Timer* pointers to work with it (similar to Character*, DynamicSprite* and so on). This requires certain attention from coder, because pointers may be "null"; on the other hand this lets you to pass Timer object as a function parameter, or return it from a function as return value (something you cannot do with basic structs in AGS).

Timer supports timeout defined in either game ticks or real time. When defining it in real-time you need to keep in mind that the timer's precision depends on FPS (game speed). If your game is running at 40 FPS then the timers are updated only once per 0.025 second (25 ms). In such case setting timeout to, say, 10 ms, won't do much sense (it will still expire after 25 ms).

Timer can be run once (default behavior) or be repeating. Repeating timers will reset themselves after every timeout and never end running. You must remember to stop them yourself when you no longer need them (this is especially important considering that number of running timers is finite).

Timer can be paused and resumed at will. Additionally, you can require all or certain timers to pause and resume with the game (when PauseGame/UnPauseGame is called).

Timers can also be created as local. Local timers remember which room the player was in when they started, and work only while player remains there. If player leaves that room, local timer will stop (default action) or pause. Timers paused this way will resume automatically when the player returns back to their "home" room.

NOTE: From the technical side, it does not matter whether variable is declared in room script or global script, either can be used to make both global and local timers. But remember that if a Timer* variable is in the room script then you won't be able to use it (e.g. stop the timer) and check it for expiration when the player is in another room. Unless that's exactly what you want, better have Timer* variable in the global script.

Since there are three causes for the timer's pause, - script command, autopause with PauseGame and autopause for local timer, - following rule is applied for unpausing the timer: timer only resumes when all three conditions are allowing to. For example, local timer which is configured to automatically pause with the game, will only unpause when in correct room AND game is not paused. If you additionally pause that timer yourself, it will require you resuming it, but resuming the timer in wrong room still won't unpause it until correct room is loaded.


Using Timer

Alright, now to the actual scripting.

Timer pointers are declared simply as:
Code: ags

Timer *MyTimer;
Timer *tBomb;
Timer *ALotOfTimers[100]; // array of 100 timer pointers


These are pointers, but timer objects are not created yet.

Here is how you create and start the new timer:
Code: ags

MyTimer = Timer.Start(50); // create a timer that runs 50 game ticks
tBomb = Timer.StartRT(10.0); // create a timer that runs 10 seconds (regardless of game speed).
// RT - means "realtime" ;)
// In case you wondered, you can pass value less than second -
MyTimer = Timer.StartRT(0.3); // this timer will run for 0.3 seconds, or 300 milliseconds

// Creating repeating timers -
SignalTimer = Timer.Start(40, eRepeat); // this timer will "expire" every 40 ticks and run again

// Creating local timers -
RoomTimer = Timer.StartLocal(2000); // this timer will run for 2000 game ticks OR until player leaves the room
ResumingRoomTimer = Timer.StartLocalRT(60.0, eTimerPause); // this timer will run for one minute, but pause if player leaves the room
AnotherLocalTimer = Timer.StartLocal(40, eTimerPause, eRepeat); // repeating local timer

// Making the particular timer automatically pause with the game
SignalTimer.PauseWithGame = true; // do this only after you created one, duh

// Or maybe you want ALL of the timers in the game to pause when game is paused?
Timer.AllPauseWithGame = true; // better do this once in the game_start()



Checking for timer's expiration is done using either of two ways.
First of all you may check timer's property EvtExpired. But because you are using timer pointers, normally you would need to first test if the pointer is not null (unless you are absolutely 100% sure it will always be created at that point):
Code: ags

if (tBomb != null && tBomb.EvtExpired)
{
    Display("BOOOOM!!!");
}


Another method takes into account the pointer fact, and works as a static function which safely manages even null pointers:
Code: ags

if (Timer.IsExpired(tBomb)) // you may pass even null-pointer there
{
    Display("BOOOOM!!!");
}



IMPORTANT: the way EvtExpired works is slightly different from built-in AGS timers.
* In AGS this flag is valid until you check it.
* In Timer module this flag is valid until the next game update. This means that you may check same timer several times, but cannot wait to check it later.


At any point in time you may test if the timer is still existing/active like this:
Code: ags

if (tBomb != null && tBomb.IsActive)
{
    // bomb is still ticking
}

if (tBomb == null || !tBomb.IsActive)
{
    // bomb timer is either did not start yet, or already run out
}



Pausing and stopping a timer is done with the other static functions.
(I was considering to add non-static counterparts but did not make them for now)
Code: ags

Timer.Pause(MyTimer); // pause it
...
Timer.Resume(MyTimer); // resume it
...
Timer.Stop(MyTimer); // stop it completely
// After timer was stopped it is completely useless
MyTimer = null; // you may even nullify pointer now



Speaking of deleting a timer, as was said - only running timers number is finite. As with other managed objects, the timer object will be only deleted after all pointers referencing it are nullified You are not obliged to do this, because timer object is small. Also, if you will assign new timer to same pointer, the old object will be safely removed from memory. But if you know that you won't be using same pointer for a while (or no longer in this game), I'd suggest to do that.


Finally, there is a way to get some information about running timer:
Code: ags

function repeatedly_execute()
{
    if (tBomb != null && tBomb.IsActive)
    {
        Label1.Text = String.Format("Ticks left: %d, seconds left: %.3f", tBomb.RemainingTicks, tBomb.RemainingSeconds);
        if (tBomb.IsPaused)
            Label2.Text = "Bomb is paused";
        else
            Label2.Text = "Bomb is running";
    }
}



Possible problems

1. Prematurely clearing or replacing pointer value.

The timer object you have in the pointer variable is the only way to control it. For the technical reasons the module itself also keeps a reference to every running timer. This means that if you nullify your pointer variable (or assign another timer to it) before the previous one has stopped, not only you won't be able to control the previous timer anymore, but the timer is not going to be deleted immediately and keep running.

For one-time timers that may not be a big issue, because they will stop on their own eventually and get deleted by the module's update function. But leaving repeatable timer like that will make it run forever, occupying a slot.

So - always Stop a timer when you no longer need it (unless it has already expired and stopped, that is).

2. Timers in non-state-saving rooms.

AGS has two types of rooms, and non-state saving rooms are special in that they do not keep their data when player leaves. What this means is even the variables are lost.
But as explained above, the Timer is a managed object, and will be kept in memory as long as there is at least one pointer referencing it. And the module itself keeps references to all running timers.

So here comes the possible issue: if you have a Timer* variable in non-state-saving room, and created a timer there, as soon as player leaves the room you will loose control over that timer. If it were repeatable timer, it will also keep running forever, as noted in problem 1).

If you need a timer in non-state-saving room:
* If you want a global timer, make a variable in global script, not room script;
* If you want a local timer that will RESUME when you return to the room, STILL declare a variable in global script. This way you will keep pointer to that timer when return to that room again.
* If instead you want a local timer that stops when player leaves the room, then just create it with eTimerStop parameter as usual, and it will get deleted properly.


Timer API reference

Code: ags

  // Maximal number of simultaneously running timers (not related to built-in AGS limit).
  #define MAX_RUNNING_TIMERS 20

  // Local timer behavior when room has changed
  enum LocalTimerBehavior
  {
    eTimerPause, 
    eTimerStop
  };

  // Flags determining the reason for timer's pause (can be combined using bitwise OR)
  #define TIMER_PAUSED_BY_USER 1
  #define TIMER_PAUSED_BY_GAME 2
  #define TIMER_PAUSED_BY_ROOM 4


  //
  // General operations.
  //
  
  /// Start the timer, giving timeout in game ticks.
  static Timer *Timer.Start(int timeout, RepeatStyle repeat = eOnce);
  /// Start the timer, giving timeout in real time (seconds).
  /// Remember that timer can be only as precise as your GameSpeed (40 checks per
  /// second, or 0.025s by default).
  static Timer *Timer.StartRT(float timeout_s, RepeatStyle repeat = eOnce);
  /// Starts local timer working in game ticks, that may be paused when player leaves the room
  static Timer *Timer.StartLocal(int timeout, LocalTimerBehavior on_leave = eTimerStop, RepeatStyle repeat = eOnce);
  /// Starts local timer working in real time (seconds), that may be paused when player leaves the room
  static Timer *Timer.StartLocalRT(float timeout_s, LocalTimerBehavior on_leave = eTimerStop, RepeatStyle repeat = eOnce);
  
  /// Tells whether timer has JUST expired. Safe to pass null-pointer.
  static bool   Timer.IsExpired(Timer *t);
  /// Stops the running timer. Safe to pass null-pointer.
  static void   Timer.Stop(Timer *t);
  /// Pause the running timer. Safe to pass null-pointer.
  static void   Timer.Pause(Timer *t);
  /// Resume the running timer. Safe to pass null-pointer.
  static void   Timer.Resume(Timer *t);
  
  //
  // Additional setup.
  //
  
  /// Gets/sets whether all timers should pause when game is paused
  static bool  Timer.AllPauseWithGame;
  /// Gets/sets whether this particular timer should pause when game is paused
  bool Timer.PauseWithGame;
  
  //
  // Current state inspection.
  //
  
  /// Tells whether timer is currently active (counting down).
  readonly bool  Timer.IsActive;
  /// Signal property telling that the timer has expired. This flag will remain set
  /// for one game tick only and self-reset afterwards.
  readonly bool  Timer.EvtExpired;

  /// Gets the home room of the local timer (returns -1 if timer is global)
  readonly int  Timer.HomeRoom;
  /// Gets what this timer should do when home room gets unloaded
  readonly LocalTimerBehavior Timer.WhenLeavingRoom;
  
  /// Gets whether this timer is working in real-time
  readonly bool  Timer.IsRealtime;
  /// Gets the timer's timeout in game ticks
  readonly int   Timer.TimeoutTicks;
  /// Gets the timer's timeout in real-time (considering current game speed)
  readonly float Timer.TimeoutSeconds;
  /// Gets the remaining time in current game ticks
  readonly int   Timer.RemainingTicks;
  /// Gets the remaining time in real-time (considering current game speed)
  readonly float Timer.RemainingSeconds;
  /// Gets current timer's paused state (0 - working, >= 1 - suspended)
  readonly int   Timer.IsPaused;
#152
Crimson Wizard and Jim Reed present:
(made for MAGS November 2017)

Last & Furious

Download links:
Dropbox: https://www.dropbox.com/s/0u7opdaxku1459c/Last%27n%27Furious.zip?dl=0
Mediafire: http://www.mediafire.com/file/wq8xgjbfyvalq40/Last%27n%27Furious.zip

Project source licensed under Creative Commons: By Attribution 4.0 (except music, which has its own authors and licenses)
https://github.com/ivan-mogilko/ags-lastfurious

Screenshots:
[imgzoom]https://i.imgur.com/YQu5AUR.png[/imgzoom]
[imgzoom]https://i.imgur.com/NhM9RUk.png[/imgzoom]


Description:
'Last & Furious' is a top-down racing game, featuring single track, two physics modes, wonky collision system and hastily set up opponent AI.

Controls: arrow keys.
Car behavior: can thrust forward, steer and brake (no backpedal, sorry).
Physics setup: when starting new race choose between "Safe" and "Wild" physics mode (they will give you two different experiences!). It is also possible to disable car-vs-car collisions (they still collide with the walls though).

Physics model in this game is actually configurable. If you feel adventurous, go to "Data" subdirectory. There you will find "race_safe.ini" and "race_wild.ini" files which contain parameters for related game modes.


Credits:
Code: Crimson Wizard;
Art: Jim Reed (was also generating tech ideas);
Music: "Car Theft 101" by Eric Matyas (www.soundimage.org), "Welcome to the Show" by Kevin MacLeod (incompetech.com).

Game DB page: http://www.adventuregamestudio.co.uk/site/games/game/2216/
#153
Well, damn, looks like I just run into one of those obscure AGS bugs. Took me several hours to, first, realize that could not be a mistake in my script, and then find out why is it happening exactly, staring into the engine code.

Following example is based on default game template.
Room 1 script:
Code: ags

// room script file

DynamicSprite *Sprite;

function room_Load()
{
  Sprite = DynamicSprite.CreateFromExistingSprite(2000);
  ViewFrame *f = Game.GetViewFrame(player.View, 0, 0);
  f.Graphic = Sprite.Graphic;
}

function on_key_press(eKeyCode key)
{
  // These lines cause the bug ======
  //if (Sprite != null)
  //Sprite.Delete();
  // ================================
  
  DynamicSprite *new_sprite = DynamicSprite.CreateFromExistingSprite(2000 + Random(9));
  Sprite = new_sprite;
  ViewFrame *f = Game.GetViewFrame(player.View, 0, 0);
  f.Graphic = Sprite.Graphic;
}


So, this code is very simple. What it does:
- It takes certain View frame, and replaces original sprite with dynamic sprite, which in turn is a copy of some character sprite.
- On every key press it creates NEW dynamic sprite from the random range of character sprites, and puts it to same View frame.
Don't bother wondering why would I need such script, that's just an example of certain actions.

Run the game and hold any key (e.g. space bar). Character's image will beging to cycle randomly.

Now, the interesting part. See these commented lines where the previous sprite gets explicitly DELETED before assigning new sprite to the same pointer? Thinking logically, that should be right thing to do, and should be safe to assume that nothing bad is going to happen?

Well, uncomment these lines:
Code: ags

if (Sprite != null)
    Sprite.Delete();

and run the game again. Hold space bar, and... you see that character's looks do not change anymore.
HOWEVER, if you walk a little and then make Roger take original direction, you will see, that the frame 0 sprite actually is different. So it DOES change after all, it's just that AGS did not redraw it in time.


So, why is this happening, and how can DynamicSprite.Delete make any difference?


AGS has character cache, where it stores last character's image with additional effects (tint, lighting, area zoom) applied. On every update it checkes whether anything has changed and if not - it keeps cached sprite.
When you create NEW dynamic sprite, and assign it to the view frame, the number of sprite is now different from old one, so AGS knows that it needs to reset cache.

But when you delete an old sprite FIRST, its SLOT number frees, and the next dynamic sprite gets created on the SAME SLOT, having same index as the old one has had! And AGS cannot detect that the change happened!

To prove this point, change the code:
Code: ags

function on_key_press(eKeyCode key)
{
  // Temporarily keep an old sprite in another pointer
  DynamicSprite *old_sprite = Sprite;
  
  DynamicSprite *new_sprite = DynamicSprite.CreateFromExistingSprite(2000 + Random(9));
  Sprite = new_sprite;
  ViewFrame *f = Game.GetViewFrame(player.View, player.Loop, player.Frame);
  f.Graphic = Sprite.Graphic;
  
  // Now delete the old sprite by referencing the temp pointer
  if (old_sprite != null)
    old_sprite.Delete();
}


If you run this code and hold space bar, the character will be animating again.


Now, the above is just a dummy script example. If you have a more complicated script, with multitude of dynamic sprites, where you cannot reliably keep track of when the old slots are freed (or rather do not want to do that), for that case I found another workaround to force AGS reset character cache:

Code: ags

DrawingSurface *ds = Sprite.GetDrawingSurface();
ds.DrawPixel(-1, -1);
ds.Release();


Thing is that when DrawinSurface.Release is called, it checks all (supposedly) places where this sprite could be used, and releases all related caches. But some drawing operations MUST be complete to make it do so! Hence we just draw one pixel outside of the sprite. While sprite physically stays unchanged, DrawingSurface object registers modification.

Now this will work too:
Code: ags

function on_key_press(eKeyCode key)
{
  if (Sprite != null)
    Sprite.Delete();
  
  DynamicSprite *new_sprite = DynamicSprite.CreateFromExistingSprite(2000 + Random(9));
  Sprite = new_sprite;
  ViewFrame *f = Game.GetViewFrame(player.View, player.Loop, player.Frame);
  f.Graphic = Sprite.Graphic;
  
  // Poke AGS to make it reset sprite cache
  DrawingSurface *ds = Sprite.GetDrawingSurface();
  ds.DrawPixel(-1, -1);
  ds.Release();
}




PS.
The actual reason for this bug is that when DynamicSprite gets deleted, it does not clears related CHARACTER caches. Which is very strange, because it clears GUIs and Room object caches. This makes me think that there could be a simple oversight.


PPS.
Also, that bothers me, but I have a suspicion that if you don't call DynamicSprite.Delete, but simply overwrite pointer with new sprite, the actual bitmap does not get deleted and stays in system memory (aka "memory leak"). This is explicitly coded so in AGS engine, and I cannot understand why. This might require a separate research.
#154
Recruitment / Artist for a small MAGS project
Fri 03/11/2017 22:39:18
Hello :).

I decided to try making a game for November MAGS, and for that I am looking for a 2D artist.

This is going to be non-adventure, arcade sports (kind of) game, which requires top-down view sprites and backgrounds, featuring simplified (may be tiled) contemporary landscape and objects (vehicles, people, etc).

Game resolution is not set, since it mainly depends on art it may be anything you can handle. I'd prefer to have at least 640x400 if possible, but that's not critical.

Personally, I am going to script the thing, but will be open for any good ideas and suggestions on game design.

I have to frankly admit that sometimes get busy with urgent tasks in my life, but even if we won't make it to the MAGS deadline, I will be willing to release this game anyway.

Please PM me if you are interested, and I will tell you more details about the game.


UPD: I found someone, thanks to everyone who PMed me :).
#155
I always had this issue when debugging AGS engine in Visual Studio before: when you break the program execution (e.g. by placing a breakpoint in the code) there was always a delay of few seconds before VS begins to respond to mouse and keyboard input, like if something is locking the input. It was happening only once per debug session, when you break the program for the first time. I had a suspicion that it has to do something with how Allegro 4 works, but could never find anything related in the internet. That was mildly annoying, and in the abscence of solution I decided to just live with it.

Now when we switched to MSVS 2015 in the master branch, this issue became much worse. This input freezing does not go away. It looks like this: program stops at breakpoint, and everything seems to be okay: no extra CPU load, the cursor is flickering in the VS as normal, but as soon as I touch the mouse or press any key, everything freezes for several seconds. This repeats every time after any signal from input device. If I move mouse too much at once I have to sit and wait for a minute before I can even shutdown debugging session forcefully.

Apparently it affects whole system, not just MSVS, because switching to other program windows does not help.
I only found one possible workaround: if I start or continue debugging, then switch to another application quickly, before next breakpoint is hit, everything works normally. But doing this trick really wastes my time alot, besides it's a game of chance.

So, right now I am almost unable to debug the code in the master branch using MSVS debugger.

What confuses me also is that since we changed to MSVS2015 there had to be other people who also tried building and running the engine. Have anyone else noticed similar thing, or it's just me?

I remember finding some kind of solution in the web a long while ago, something about hacking a registry, and IIRC that kinda worked (although not 100%), but seems bit unreliable to me, also unfortunately I forgot what it was and how to search for it.


NOTE: this does NOT occur when debugging Editor, even if I put breakpoints in C++ native code.

EDIT2: After further testing I can confirm, a call to Allegro's function install_mouse causes mouse issues in the debugger, call to install_keyboard locks up keyboard input inside MSVS correspondingly.

EDIT3: Finally was able to find the threads on Allegro forums, confirming and explaining this issue:
https://www.allegro.cc/forums/thread/615043
https://www.allegro.cc/forums/thread/615012/1009606#target

QuoteAllegro grabs the system keyboard and mouse. So when the game crashes or reaches a breakpoint, the IDE pops up, but all mouse movements and keyboard events have a several seconds lag because the allegro handlers simply do not answer. Mouse buttons do not work at all. Imagine to single step like that.

UPD4:
Another couple of descriptions of the similar problem. I am not completely sure if the cause is same, but description of the symptoms match:
http://the-witness.net/news/2012/12/finding-and-fixing-a-five-second-stall/
https://stackoverflow.com/questions/9727327/windows-keyboard-hook-hangs-debugger

#156
Following package contains latest prebuilt libraries:
https://www.dropbox.com/s/4p6nw6waqwat6co/ags-prebuilt-libs.zip?dl=0

- for the Windows engine 3.4.1 (built with VS2008)
- for the Windows engine of master branch (built with VS2015).
- for the Editor of master branch (.NET 4.0 compatible third-party assemblies that need to be copied to References folder)


We probably may find a better place to host these later.
#157
Site & Forum Reports / AGS Error reports
Sun 28/05/2017 15:48:09
Hello.

There is a "send report" feature in AGS Editor; user may press a button on error message form to send report to server.
Report is sent to: http://www.adventuregamestudio.co.uk/errorReport.php

Is this feature still works on server side, and is it possible to read sent reports? Right now this functionality seem to be completely useless, because developers cannot access these reports.
#158
General Discussion / Babylon.js game framework
Thu 25/05/2017 01:46:10
I've never programmed for Web in any way, except for some experiments with HTML and jscript (I think?) more than a decade ago, but recently a former co-worker suggested that I could learn a WebGL framework called Babylon.js to occasionally aid him with some stuff.

Babylon.js is a framework written in TypedScript (which is a kind of JavaScript extension) which works with HTML5 and WebGL. Basically it is a thing to create 3D scenes and games, presentations, etc. This framework is open source too, and 100% free (from what I saw). Their website even have a "sandbox" where you may try out some smaller scripts before making a bigger project.

I do not remember if I ever programmed in JavaScript before, which is a shame I guess; the language appeared to be easy and pleasant to use. There is a very good JS refernce provided by Mozilla, and if you know at least any C-like or other scripting language (even AGS script :) ) you should get into it in no time.
Of course one would have to learn a bit about working with 3D space first, even if you want to make 2D games there (I believe latter should be possible, although I haven't found orthogonal (2D) camera preset yet).

Compared to Unity3D, it does not provide any IDE (Editor). Although you may use some tool to work with JavaScript, like Visual Studio, or another, but that's not required (you may use just a text editor). To run your game you need just an up-to-date browser (you may even create standalone version and run offline if you download Babylon engine files from their site).
This has natural advantages and disadvantages. I think it is easier to create quick prototypes, because you do not need to install Editor and C# tools. On other hand, lack of default visual editor may make more advanced scenes harder to work with. Depends on how you do things, I guess.



Anyway, I spent few days doing tutorials and created this don't-yet-know-what-is-it prototype:
https://www.dropbox.com/s/y6fdo428ugsuass/hexmap-test.zip?dl=0

This is just an HTML file, you need to be online to run it because it references Babylon engine from their website. But all my script is right in HTML's body and may be viewed in any text editor. It's a bit mess for now, because I haven't tried to organize it properly, splitting into js files etc. It does not do much for now anyway.

Controls are:
* hold LMB and move mouse to rotate camera
* same with CTRL - move camera
& Mouse wheel - zoom in/out.
* A/S - rise and lower map tiles under cursor
* SPACE - set "marker" thingie on the tile under cursor.
* F5 - restart (obviously)
#159
I've met another trouble with removing hacks from AGS to be able to update it keep every port with latest version of Allegro. I described it here: https://github.com/adventuregamestudio/ags/issues/407

In short, there is only one way that will work on all platforms for now: to load up whole FLI movie into memory and play it that way. How good is that? Depends on how large flics are. Is there any limit for them?

Alternatives are:
- patch Windows version of Allegro and let it play FLI from custom game package. But other ports will work only if FLI video is lying in game directory as external file. This effectively breaks all the existing games with FLI videos, until someone rips FLI out of package.
- find another library that plays FLI and add its as a new dependency to AGS.
- copy whole FLI player into AGS.
#160
I finally seem to make OpenGL work in any display mode under Windows:
http://www.mediafire.com/file/9gm6xt1d88xt45k/acwin-3.4.1-opengl.zip
http://www.mediafire.com/file/vh847jgpeqt6wq7/acwin-3.4.1-opengl2.zip
http://www.mediafire.com/file/5qsa7vi6d1ra27e/acwin-3.4.1-opengl3.zip


"OpenGL" should be available in drivers list in winsetup.

I believe understand making scenes in 3D better now... and also learnt that with 3D it is so much easier to do a lot of unnecessary and duplicating operations, with coordinate translations and camera positioning countering each other. Until you change something you do not notice that.


If I can find time, I may try to make it work on Linux too, because Linux port was suffering from lack of hardware-accelerated renderer all those years.
SMF spam blocked by CleanTalk