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

#421
In regards to the problem of returning from the middle of "repeatedly execute":
If there's multiple unrelated stuff updated there, like for example: update puzzle, update character position, update blinking lights on background, and so forth, then I do recommend moving unrelated parts of code into separate functions and call these functions from rep-exec. Then each part will be updated separately, not conflicting with each other.

For a dumb example:
Code: ags
function UpdateTwoObjects()
{
    // Idk if this code itself is correct, I'm just copy/pasting it for this example
    if (object[1].Visible == true) { myCounter1 = 4; myCounter2 = 4; return; }
    if (object[2].Visible == true) { myCounter3 = 4; myCounter4 = 4; return; }
}

function UpdateCounters()
{
    // all the counter stuff
}

function room_RepExec()
{
    UpdateTwoObjects();
    UpdateCounters();
}

If updating counters should be skipped awhole under some condition (like objects visible or not), then you may solve that by adding a early return like this:

Code: ags
function UpdateCounters()
{
    // don't update counters if something is off
    if (some condition) { return; }

    // all the counter stuff
}

PS. By the way, this "early return" code style is one that opposes the aforementioned Djikstra's proposal, apparently.
This pattern has its name in computer science, but I keep forgetting it.
#422
I'm sorry, I did not realize that the thread does not give clear instructions, but only raised the question apparently. I think it should be unstickied to prevent confusion, and then someone could write a proper one with direct instructions on how to resolve this problem.
#423
Quote from: Baguettator on Thu 06/03/2025 04:54:00Now, it's only missing gradient implementation

What is that?
#424
Quote from: greg on Thu 06/03/2025 02:41:42Character.AddWaypoint() appears to be restricting characters' movement to walkable areas.

I don't see it restricting movement, but I see that it teleports character back to walkable area when it finishes walking if there was Walk with eWalkableAreas just before adding a waypoint, because of these fixes I made. This logic is broken now.

I just noticed now that previous versions of AGS never fixed character's position in the end of walk, only if "StopMoving" was called explicitly. Somehow I understood this wrong. Now it works differently than before, and this affects a number of other things.

Engine only fixes the position if the walk is marked as "walking by walkable areas". So if the walk was started by a normal Walk with eWalkableAreas , AddWaypoints don't change that, and engine still considers this walk to be a walk over walkable areas. This is a property of whole "walk", not each segment.


EDIT:
Of course this means that AGS historically had this error: if you call AddWaypoint after Walk with eWalkableAreas, and then call StopMoving in script while character is walking on a non-walkable area, then the character will be moved to the nearest walkable area. Because it remembered that the first walk was done using eWalkableAreas.

Now the situation is worse because I made that automatic fixup after the end of walk, so it's going to happen every time character finishes walking after AddWaypoint.

What are the options of fixing this?
Option 1. Whenever AddWaypoint is called, the walk is marked as "eAnywhere". Of course this will mean that if character is stopped during first walking stage, they will not get position fixed even if it was called with eWalkableAreas.
Option 2. Modify the walking logic to store the "uses walkable areas" flag per stage. This will also require to modify savegame format because walking plan is saved there.

EDIT 2:
And then there's also a problem of backwards compatibility, because the new fix in the end of walking may change the position where the character ends up...

It's quite possible that I made a mistake with this fix. I did not find why does the character end up on the nonwalkable area at all. Is it that pathfinder makes a mistake and sets the end of the path there, or is it that character makes a mistake when moving?
Maybe I should change this to not search for walkable area, but place at the explicit coordinates that were found by the pathfinder instead.
And if this contradicts old game behavior, then do this only for the games made with the new version of AGS, to keep old game behavior unmodified...

I will have to make tests that implement faulty case when character ends up on a non-walkable area, and include these into automatic tests, to keep these potential problems visible at all times.
#425
This another temp build:
https://cirrus-ci.com/task/6401719766089728

Fixed:
1. Hotspot selection not repainted properly.
2. Engine crashing when trying to draw a default speech box without textwindow gui.
#426
I'm afraid that I won't be able to tell what is going on without knowing more, or directly debugging the game project.

Is it possible for you to send me your project files privately so that I could take a look?
#427
Well, this error means that the game was not compiled correctly. But I cannot tell how exactly that could happen.

Did you upgrade the version of AGS recently?
Do you remember what did you add to the game right before this began to happen?
#428
Quote from: Marion on Wed 05/03/2025 18:18:12It's the version v4.0.0

There should be 4 numbers, the last is important for me to know.
#429
So, this is happening when running a compiled game.
Have you tried to fully rebuild it?
Please tell what version is this exactly (you can see the full version numbers in Help->About menu).
#430
Quote from: Monsieur OUXX on Fri 29/09/2017 10:28:17this thread might benefit from being sticky.

As this thread does not give clear instructions, perhaps it should be unstickied?
I am not an expert in this question, but it does not look helpful enough, and posts are too old. Not something you can give a link to if anyone asks about this problem.
#431
Could you upload the image somewhere else, because it does not show for me?

Also, you can usually do Ctrl+C when error window is open, that will copy the text to clipboard, and then you can paste it into the forum post.
#432
Engine Development / AGS 4: Touch input API
Wed 05/03/2025 12:47:44
This has been a request for a long while, but somehow we never got to implement touch API in script.
@eri0o has started to research this and made a draft, but it stayed unfinished for some time.

Recently I took his old draft and updated to a working version, ready to be included into the engine.

The PR:
https://github.com/adventuregamestudio/ags/pull/2692
Test build may be downloaded here:
https://cirrus-ci.com/task/5043738189234176


The API is very simple for starters, there are no sophisticated gesture detections, only basic things.

First there's array of TouchPointer objects that let to learn current state of N pointers, where "Pointer" is an abstract "device" that can touch a sensor. Normally this is a finger touching a touch pad or touch screen. Mouse can be emulated through this as well:

Code: ags
managed struct TouchPointer {
  /// Gets this touch pointer's identifier.
  import readonly attribute int ID;
  /// Gets whether this touch pointer is currently down (in touching state).
  import readonly attribute bool IsDown;
  /// Gets this touch pointer's X screen coordinate.
  import readonly attribute int X;
  /// Gets this touch pointer's Y screen coordinate.
  import readonly attribute int Y;
};

builtin struct Touch {
  /// Number of touch pointers registered by the game engine.
  readonly import static attribute int TouchPointerCount;  // $AUTOCOMPLETESTATICONLY$
  /// Accesses a touch pointer state by its identifier.
  readonly import static attribute TouchPointer* TouchPointers[];  // $AUTOCOMPLETESTATICONLY$
};

Besides the pointer states, there are pointer callbacks that you may add to your code:

Code: ags
function on_pointer_down(int pointer, int x, int y);
function on_pointer_up(int pointer, int x, int y);
function on_pointer_move(int pointer, int x, int y);


Here's an example of a game built for Android, which requires 2 fingers to control:
https://www.dropbox.com/scl/fi/6pqtttp2pwzyshqgn9ceg/ags4-touch-test-apk.zip?rlkey=764b7unhlrm9lafv3b4qnuy2f&st=f7h1x5um&dl=0

It features 2 on-screen "pads", one of which works like a joystick and another has 4 "buttons". These may be interacted with 2 fingers simultaneously, and it does not matter which finger you use on what.
(Now when I think about it, it's possible to use more fingers, in which case extra fingers will probably override each others.)
I apologize for the crude gfx and low resolution, i used lazy design and "programmers art".
But I think it serves a proof of concept.

Here's the game project:
https://www.dropbox.com/scl/fi/1ozjmq0yn0qi3103leb3r/ags4-touch-test.zip?rlkey=em6spjqj1z2a9cazpvss9ojq0&st=rn64iyj2&dl=0


The related code looks like this:
Spoiler
Code: ags
int JoystickRelX, JoystickRelY;

void HandleJoystickMotion(TouchPointer *p)
{
    int rel_x;
    int rel_y;
    if (p != null)
    {
        rel_x = p.X - gJoystick.X;
        rel_y = p.Y - gJoystick.Y;
    }
    else
    {
        rel_x = gJoystick.Width / 2;
        rel_y = gJoystick.Height / 2;
    }

    int btn_x = (rel_x - btnStick.Width / 2);
    int btn_y = (rel_y - btnStick.Height / 2);
    if (btn_x < 0) btn_x = 0;
    if (btn_x > gJoystick.Width - btnStick.Width) btn_x = gJoystick.Width - btnStick.Width;
    if (btn_y < 0) btn_y = 0;
    if (btn_y > gJoystick.Height - btnStick.Height) btn_y = gJoystick.Height - btnStick.Height;
    btnStick.X = btn_x;
    btnStick.Y = btn_y;
    
    JoystickRelX = rel_x;
    JoystickRelY = rel_y;
}

void HandlePlayerJoystick()
{
    int dx = JoystickRelX - gJoystick.Width / 2;
    int dy = JoystickRelY - gJoystick.Height / 2;
    float fdx = IntToFloat(dx) / IntToFloat(gJoystick.Width / 2);
    float fdy = IntToFloat(dy) / IntToFloat(gJoystick.Height / 2);
    player.x += FloatToInt(fdx * IntToFloat(player.WalkSpeedX), eRoundNearest);
    player.y += FloatToInt(fdy * IntToFloat(player.WalkSpeedY), eRoundNearest);
    if (player.x < 0) player.x = 0;
    if (player.y < 0) player.y = 0;
    if (player.x > Room.Width) player.x = Room.Width;
    if (player.y > Room.Height) player.y = Room.Height;
}

void HandlePadMotion(TouchPointer *p)
{
}

void HandlePadDown(TouchPointer *p)
{
    int rel_x = p.X - gPad.X;
    int rel_y = p.Y - gPad.Y;
    
    if (rel_x < gPad.Width / 2)
    {
        if (rel_y < gPad.Height / 2)
        {
            player.SayBackground("BLUE");
        }
        else
        {
            player.SayBackground("GREEN");
        }
    }
    else
    {
        if (rel_y < gPad.Height / 2)
        {
            player.SayBackground("RED");
        }
        else
        {
            player.SayBackground("YELLOW");
        }
    }
}

// called on every game cycle, except when the game is blocked
function repeatedly_execute()
{
    HandleJoystickMotion(null); // reset
    for (int i = 0; i < Touch.TouchPointerCount; i++)
    {
        TouchPointer* p = Touch.TouchPointers[i];
        if (p.IsDown)
        {
            if (p.X >= gJoystick.X && p.X <= gJoystick.X + gJoystick.Width &&
                p.Y >= gJoystick.Y && p.Y <= gJoystick.Y + gJoystick.Height)
            {
                HandleJoystickMotion(p);
            }
            else if (p.X >= gPad.X && p.X <= gPad.X + gPad.Width &&
                p.Y >= gPad.Y && p.Y <= gPad.Y + gPad.Height)
            {
                HandlePadMotion(p);
            }
        }
    }

    HandlePlayerJoystick();
}

function on_pointer_down(int pointer, int x, int y)
{
    if (x >= gPad.X && x <= gPad.X + gPad.Width &&
        y >= gPad.Y && y <= gPad.Y + gPad.Height)
    {
        HandlePadDown(Touch.TouchPointers[pointer]);
    }
}
[close]
#434
Quote from: RootBound on Wed 05/03/2025 11:50:312. If I delete all the text from a GUI button, the editor switches to editing the GUI as a whole and not the button.

Please clarify the steps for this? Simply deleting a text in button's property does not do anything.
#435
This has been the standard behavior of AGS for years: if you start the test run from the editor, it deletes a compiled file from Compiled folder.
There were certain reasons for this in the past, but that no longer is a case. So this behavior was removed starting from AGS 3.6.2.
#436
I forgot to post this, this is a new temp build which contains these new modes, in case somebody wants to try:
https://cirrus-ci.com/task/6640724495564800

This build brings back an ability to draw transparency to drawing surface by replacing pixels.
This is done by setting "DrawingSurface.BlendMode = eBlendCopy", which will copy the color to destination instead of merging with the underlying color.

There are also 2 accompanying modes: eBlendCopyRGB and eBlendCopyAlpha, which copy either only RGB part but keep surface alpha, or copy only Alpha but keep surface color. These may be used, for example, to make part of the surface half-translucent while keeping its current image, or vice versa recolor part of the surface while keeping its translucency.
#437
Quote from: greg on Tue 04/03/2025 03:04:06However, it's creating a new issue when a character intentionally walks off a walkable area (a call to chr.Walk() where WalkWhere=eAnywhere).

Of course I forgot to test the opposite case, and did not notice that this still does not work correctly.

Here's another build:
https://cirrus-ci.com/task/6345292460589056

I would need to update our automatic game tests and include walking test there.
#438
AGS supports up to 90k imported sprites. There's a known issue that Editor may run out of memory if you imported a big number of sprites during same session without saving (this is resolved by saving periodically).

The error sounds like some internal problem in the editor. I don't know in which situations it may appear though.
Does this happen to any image file or particular ones?
Does this happen when you just started to work with the editor, or being working with it for a while?

#439
A demo of what's coming in the next AGS 4 update:
An example of Button having a BlendMode "CopyAlpha", moving across GUI:



Previously this would require to do a mix of operations over dynamic sprite, with the use of CopyTransparencyMask function.
#440
Quote from: greg on Mon 03/03/2025 00:58:37With the linked build, I'm still experiencing the same issue where the character ends up 1 pixel off the walkable area. I've addressed it by adding a check to my Walk() and FaceDirection() wrappers where, if chr isn't on a walkable area, they're moved to Room.NearestWalkableArea(chr.x, chr.y);

Of course, I made another mistake, and did not fix it!

Here's a new build:
https://cirrus-ci.com/task/6277045589639168
SMF spam blocked by CleanTalk