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

#801
I don't think it's proper to move big part of functionality from one class to another only for the purpose of editing a tooltip.
Is there a good reason to have this functionality moved to ScriptEditorBase? In general this is a question of the purposes and roles of these classes.
ScriptEditorBase was meant to be a parent class for editor pane, which may have multiple different controls on it, besides script control. I suppose that it's better to have script parsing and related behavior (such as styling and tooltips) as close to the script text control itself as possible, which is ScintillaWrapper atm.


Events are a common solution for customizing behavior.
If it's necessary to inject some extra text to tooltip, you could add a event to ScintillaWrapper, subscribe in ScriptEditorBase, and provide reaction there.
Such event could pass a keyword and its information (what is it) in its arguments.

The async operation is a problem. But maybe it could display standard tooltip first, trigger the variable request, and then modify (replace) tooltip with an extended text as soon as an answer was received. OTOH, since the tooltip is displayed with a delay anyway, maybe the event could be triggered when the tooltip "timer" starts, and then the variable request will be processed in parallel with this delay.

Not looking into the code yet, only imagining, this could work like this:
1. ScintillaWrapper realizes it needs to display a tooltip, and fires event.
2. ScriptEditorBase receives event, checks if the editor is running a game test, and queries variable.
3. As soon as ScriptEditorBase gets an answer, it tells ScintillaWrapper to display extra text in tooltip. OR displays its own tooltip, besides / below the scintilla's one (idk if easy to do).

In this scenario, you should also detect when calltip was cancelled by moving cursor elsewhere.
#802
Before assigning any effect to a walkable area, we'd need to define the effect itself.
(And then it also has to be manually assignable too.)

So what is this "blur" effect exactly, can you describe it logically?
#803
Well, there still may be few minor additions, for example I wanted to try adding a starting monitor selection in setup.

Also, we could update to VS 2019 at least (which would change the required VC runtime).

There may be as many Beta updates as necessary - until we're certain that things are stable.
#804
Quote from: eri0o on Sat 23/11/2024 11:10:57I am looking at AGS Script function calling, and saw this method in the code

https://github.com/adventuregamestudio/ags/blob/62894ea31074f7266db7e1f23ed17ba89aece60a/Engine/script/cc_instance.cpp#L379

It looks like it has a bunch of things to improve, it does for inside for through strncmp and also does atoi. If I understood this is done on each function call, I think this is one of those things that if necessary should be patched before the script is run

This "for" loop there likely may be replaced by a hash map, initialized when creating a script instance.
#806
Quote from: Joacim Andersson on Sat 23/11/2024 05:44:13My second question remains though, do AGS have a generic data type?

No, that's one of the big limitations of this script.
It has no generic data type, no C#-like generic functions, nor C++ like templates.

It does support extending a struct, and up-casting from child to parent struct pointer (if these structs are declared as "managed"), but does not support down-casting at the same time (latter may be added in AGS 4 in theory, where we implemented some form of runtime type detection).
#807
Updated to Beta 3
(Please use download links in the first post)

Includes all the fixes from 3.6.1 Patch 8.

Own changes:

Editor:
 - In "Start New Game Wizard" game template selection now displays template's description right in the dialog.
 - "Game statistics" now have Ctrl + F2 shortcut instead of F2.
 - F2 can be used for starting editing names of items in the Project Tree (ones that support that) and folders in the Sprite Manager.
 - Added a multiline Text edit window for Button and Label controls, that may be called by Ctrl+E, from context menu, or by pressing "..." button of the Text property in the Properties grid.
 - In Room Editor, during any area drawing mode Ctrl + LMB now works as area picker regardless of the currently selected tool.
 - Editor will now report any missing script functions that are assigned to events but not present in script as warnings when compiling the game.
 - Fixed font preview not updating after importing a new font over. (regression in 3.6.2 Beta)
 - Fixed editing Color property of multiple selected GUI controls.

Scripting:
 - Dynamic arrays now have Length readonly property that returns their number of elements.

Script API:
 - Events eEventGUIMouseDown and eEventGUIMouseUp now get additional parameters: mouse button, mouse x and y positions.
 - Added RestoredSaveInfo struct which contains information about game save's contents,
 - Support "validate_restored_save" callback, which lets user to validate restored saves with mismatching data and request cancellation or continuation of restoring this save.
 - Added FileSortStyle and SortDirection enum, and File.GetFiles() function that returns a dynamic array of filenames found using certain pattern, and optionally sorted by name or time, in ascending or descending order.
 - Added SaveGameSortStyle enum and Game.GetSaveSlots() function that returns a dynamic array of save slot indexes, optionally sorted in certain way.
 - Added Game.ScanSaveSlots() that scans a range of game saves and tests them for compatibility, using "validate_restored_save" too if it's present in user script. This action is not run immediately, but is scheduled to be executed after current script ends. It reports of scanning completion by sending eEventSavesScanComplete event.
 - Added optional "fileSortStyle" and "sortDirection" parameters to ListBox.FillDirList().
 - Added optional saveSortStyle and sortDirection parameters to ListBox.FillSaveGameList().
 - Added ListBox.FillSaveGameSlots(), which initializes a list of saves from a dynamic array of save slot indexes.
 - Added Object.DestinationX and DestinationY properties, complementing ones in Character.
 - Added SendEvent() function that allows to trigger "on_event" function calls in script. Special event value eEventUserEvent may be used as a base index for user-defined events.
 - Add SaveComponentSelection enum and game option OPT_SAVECOMPONENTSIGNORE, which lets to skip certain components when saving or restoring a game. This has dual purpose: reduce number of things in game that may break older saves by simply not having them in a save, and also reducing the size of game saves on disk (e.g. in case of dynamic sprites). Note that all things that were not restored from the save will retain their *current state*.

Engine:
 - Engine now potentially supports reading saves made in older game versions with different content, so long as these saves have *less* data in any given type (i.e. less Characters, or less controls on a certain GUI, or less variables in script, and so forth). This feature is enabled by having a special "validate_restored_save" function anywhere in the game script, that accepts an argument of type RestoredSaveInfo. RestoredSaveInfo contains various information about the restored save, and "Cancel" property, that must be explicitly set to "false" in script in order to allow to restore such save.
 - Engine supports returning to previously saved rooms which have less script data. It's important to remember though that it does no validation of restored room state on its own.
 - Engine no longer quits with error in case a script function assigned to a Room event is missing. Logs warnings about missing script functions assigned to any events.
 - Support calling StopDialog() inside a dialog script, that will schedule dialog's stop command at the end of the current option script.
 - Added new config setting to "access" section called "textreadspeed" which lets to override game's text reading speed parameter.
 - Fixed calling Dialog.Start() inside a dialog script would create a nested "dialog state", which could eventually lead to internal mistakes and program stack overflow. Dialog.Start() will now schedule a proper dialog topic switch, equivalent to "goto-dialog" command.
 - Fixed Character may get stuck in "move without animating" state if Move called before Walk. (regression in 3.6.2 Beta)
 - Fixed 8-bit room bgs in 32-bit game are imported filled with "magenta". (regression in 3.6.2 Beta)
 - Fixed crash on game quit if there was any queued music. (regression in 3.6.2 Beta)

WinSetup:
 - Added "Text reading speed" to "Accessibility" settings tab.
 - Fixed setup could save wrong setting values in categories located on other tabs, if player never opened these tabs.
 - In "disabled" section of config "access_skipstyle" setting lets disable all options in setup related to the speech and text skipping.



This update finally adds the feature that was one of the reasons to plan 3.6.2 release (at least for me): a support for loading saves from older game version. This function is currently limited in what it can do: you can only load saves with *less* data, and it will be stable so long as you did not change the order of previously existing things. That's why it's primarily purposed for patching already released games, and not for creating multi-chapter games or games with DLCs, for example (although, I suppose, one could try to pull that off too with certain effort).

This is still experimental, and requires testing potential use cases.

Another complementary feature is a function that *prescans* saves without restoring them. This allows to test which saves are "safe" to load prior to displaying them in the save/load menu, for example.

All this have to be properly documented and explained. Unfortunately I'm too tired now, so for the moment I'll give two links to the tickets in our github tracker, which contain overview of these features:
* Support loading older saves: https://github.com/adventuregamestudio/ags/pull/2489
* Prescanning saves: https://github.com/adventuregamestudio/ags/pull/2579

And the forum thread that discusses this all:
https://www.adventuregamestudio.co.uk/forums/engine-development/load-older-game-saves-into-updated-game-attempt-2/



OTOH I'd very much prefer to wrap things up in 3.6.2, stop adding things to it, and focus on testing, fixing and documenting what's already added.
#808
Quote from: Joacim Andersson on Sat 23/11/2024 02:42:57I wish the documentation were a bit more extensive on all of the OOP stuff.

Yes it is true, some parts of the manual have unfortunately been neglected for a while. This is mostly because of small number of contributors to the engine.

Quote from: Joacim Andersson on Sat 23/11/2024 02:58:20But what is the plan for AGS, will there be more 3.x releases before 4.0 is ready?

Eventually we'd like to focus on AGS 4, and only do patch releases to 3.x.
AGS 4 has been delayed for too long, because of inconsistent planning...

3.x is a backwards compatible engine which can run many old games. Plus it's a way to upgrade game projects from earlier years, if someone wants to move them to AGS 4 they'd have to go through 3.x first. So it will be around as a backup version.
#809
Quote from: Joacim Andersson on Sat 23/11/2024 02:42:57So basically they work like property getter and setters in C#?

That is correct.

Quote from: Joacim Andersson on Sat 23/11/2024 02:42:57Does Lambda functions also exist?

No.
#810
Quote from: Joacim Andersson on Sat 23/11/2024 02:28:01Yeah ok, so basically you have to create a Get and a Set method (much like Java) but above it looked like the read-only data variable could be read by the int MyStruct::get_Data() method, which isn't declared. So it looks like that would be called when you use
Code: ags
value = myStructInstance.Data
Have I understood that correctly? If so it's still different from having a GetData() and a SetData() method.

Yes, that is correct, if you have declared an attribute Data, then you don't need GetData and SetData methods, but you need to define get_Data and set_Data methods.

I made a small mistake in the example above, in case get_Data was not declared in the struct explicitly, then its definition has to be done using an "extender function" syntax

Code: ags
int get_Data(this MyStruct*)
{
    return this._data;
}

This is also explained in the article that I linked above.
#811
Quote from: Joacim Andersson on Sat 23/11/2024 01:58:19Will AGS 4 have both getter and setter properties? I would love that, to get rid of all global variables.

AGS already has properties with getters and setters, as well as ways to protect fields of structs from public access

The manual is a bit lacking in regards to this topic unfortunately, but the general explanation may be found here:
https://adventuregamestudio.github.io/ags-manual/OOProgramming.html
#812
Quote from: Snarky on Fri 22/11/2024 20:16:24If you are thinking of ways to extend this feature, would it perhaps be possible to add a way to merge the sprites before scaling, to deal with this "bug"?

I was not thinking about extending "follow character" feature much, I believe it's too limited, and there has to be something else for the long run, like one of the two mentioned earlier ideas: composite views or parent-child object linking.

As for "merging sprites", baking multiple sprites together is technically possible, but if it's done automatically by the engine then it's not as trivial and has to be carefully designed. Definitely this must not be done "on the fly", as this may decrease performance, countering all the performance improvements we did in the last couple of versions. There have to be clear defined condition under which this happens. These baked sprites have to be in the cache too, and for the cache they have to have a way to identify which sprites are merged, and probably which effects were on these sprites too, etc etc.

I cannot tell if this work will be justified by fixing a small glitch that may be fixed in other ways.

Besides, right now there's already an existing method involving dynamic sprites, which is under full user's control. It's not immediately clear to me whether automatic solution will have much advantage over that.
#813
Quote from: eri0o on Fri 22/11/2024 11:02:01That wouldn't work in reality once you need the character to speak you need to turn that off somehow - the loop/frame syncing.

True, but this will depend on a use case. An original proposal was referring to attaching heads to characters, meaning they would have to be animated separately anyway during speech. So while the character is walking, it could follow with loop and optionally frame syncing, and when character is speaking the script will call FollowCharacter once again without loop/frame syncing, and run speech animation.

EDIT: But then, loop and frame are not the only things that have to stay in sync. Scaling too. And maybe other visual effects. So that's still not a trivial situation.
#814
Quote from: eri0o on Fri 22/11/2024 10:26:59There is one here that got me curious

https://www.adventuregamestudio.co.uk/site/projects/open/278/

It then suggests this idea of composite views


I had this idea of composite views very early on, but never got to actually design that.
Besides the composite views there's also an idea of parent-child object relation, which example may be seen in Direct3D / SpriteVideo plugin.

But I should have realized earlier that there are big changes, and then there are small additions to existing functions, and they may co-exist for some time.


Reading the proposal of FollowCharacter switching follower's loop today, I'd rather make that work, because it's easy. This can be done by adding a third parameter to FollowCharacter (maybe flags: sync loops + sync frames etc), or adding new special value for distance (like FOLLOW_EXACTLY_LOOP, FOLLOW_EXACTLY_FRAME), and then adding extra internal flag to character, which tells to switch loops and/or frames when following someone.
#815
I completely forgot that these exist...

After a very quick look, some of these have already been completed,
still there are few that seems like good ideas, and not present on github tracker.
#816
For a completion sake there has to be:
- Following or FollowsCharacter or FollowTarget property - tells whom this character is following now; returns null if not following.
- FollowerCount;
- Followers[] indexed property, let iterate everyone who follows this char;
- maybe readonly attributes that tell distance and eagerness (?) not sure if necessary. (Also, I never learnt what these mean precisely, except for FOLLOW_EXACTLY)
#817
I need an advice in regards to the new scripting API.

In the version we have an ability to do different file sorting when filling in list boxes using ListBox.FillDirList(). And I'm also currently working on another function which scans for saves and returns a dynamic array with slot numbers (for the purpose of prescanning valid saves etc, but that's a long story). It also can do sorting. This made me think that it's not a too bad idea to add optional sorting args to ListBox.FillSaveGameList() as well.

Currently there are two types of file sorting implemented:
- by name
- by time (modification time)

Here's where I realized that in case of saves there is an ambiguity in what to consider a "name". Initially I thought filename, because it also matches the slot number due to how save files are called; which would make "sort by name" = "sort by slot number".

But now, since ListBox is affected, and when ListBox is filled with saves it fills save descriptions, I begin to have doubts.
Is the description also valid case for sorting saves?

If yes, then how to deal with this situation?

I see 3 variants:
1. Consider sorting by "Name" be sort by description in case of filling ListBox, and loose ability to sort by a slot number.
2. Add another sorting style by "Index" or "Number" into the list of file sorts (it will be called e.g. "eFileSort_Index"), so have both sort by slot number and description.
3. Create a completely separate "save sorting style" which will have sorting by SlotNumber, Description or Time.


EDIT: Hmm, i'm gradually leaning towards separate enum, i.e. SaveSortStyle, because files may in theory be sorted by parameters that are not meaningful for saves at all (like size on disk), and saves may require specific ways to order too.
#818
Quote from: Joacim Andersson on Thu 21/11/2024 22:24:26So does that mean that a readonly can be initialized once, much like a readonly in C# can be initialized in the constructor. However, since AGS doesn't have classes and constructors, does that mean that a readonly is not initialized when created like a normal int is initialized to 0?

AGS has "structs", which are like something in between struct and class in functionality.
But you are right that it does not have constructors just yet. There will be soon in AGS 4.0 though (we're working on that).

Traditional use of "readonly" in structs was for attributes (aka properties). That would make these gettable but not settable.

This may be done in 3.* already, and is thoroughly used in standard engine API:

Example of user script:
Code: ags
struct MyStruct
{
    import void InitMe(int data);
    import readonly attribute int Data;

    protected int _data;
};

Code: ags
void MyStruct::InitMe(int data)
{
     _data = data;
}

int MyStruct::get_Data()
{
    return _data;
}
#819
Quote from: eri0o on Thu 21/11/2024 20:38:49In ags4 with the new compiler, I believe readonly is the keyword you use for const like behavior. And there I believe that it also works in non-dynamic array size.

AGS 4 supports both "const" and "readonly",
where "const" is a compile-time constant, and it is replaced with actual value during compilation;
while "readonly" is a runtime-time constant, meaning it may be initialized by any expression, including calling a function, which result can be only calculated at runtime.
#820
By the way, AGS should be able to import 4-bit PNG format starting with upcoming v3.6.2 (and in AGS 4).

However, when it does, it converts it to 8-bit, IIRC, which may not be what you like in a 32-bit color game.
SMF spam blocked by CleanTalk