Animmaniac's Recent Forum Activity

  • I thought a bit more and ended up at the conclusion that instead of creating a new generic 'Then' or 'Next' system condition (that doesn't mean much), it would be clearer if it was a special condition from the LocalStorage object, or the Pathfinding behavior kept it's 'On path found' condition and so on. 'On path found' describes a lot better what it does than a generic word like 'Next'. The same for something like 'On requested data ready' for the LocalStorage, it's a lot more meaningful.

    My proposal is to create a new type of event, a kind of "scoped trigger" (in the sense of a trigger which acts depending on scope). It would have a different icon (like the different arrows for regular trigger and loop conditions) to differentiate it from the rest.

    When placed below an event, it should automatically recognize the scope and act only in the scope of the previous event. In the case of the LocalStorage it could be an "On all completed" trigger for the previous 'request data' actions from the event above. For the Pathfinding behavior it could act as a regular trigger, but only fire for the previous 'Find Path' action from the event above. This allows to make contained triggers.

    Exploring the possibilities, this "scoped trigger" could act locally only when placed as a sub-event, triggering only from the actions in the scope of it's parent event. This opens some new possibilities: when placed as a top-level-event it could be triggered by any related event, responding to any call throughout the event sheet. So it could be more versatile acting both as a local trigger (as a sub-event) or global (as a top-level-event) depending on scope. This new type of trigger would even allow local functions, that could be really handy.

    Now focusing on the LocalStorage, I believe it would be possible to give options to use it both synchronously or asynchronously. For really small data like simple variables (probably the most common use), a synchronous storage works very well with a small performance impact, but compensates greatly with it's easiness of use. For big data like long strings, an asynchronous storage is better because it doesn't stall the whole event chain while reading or writing, but it complicates a lot the use of events.

    So why not keep both and let the user choose depending on the circumstance or data type?

    The LocalStorage could have a traditional set action with a get expression that works synchronously for small data, stalling the event execution until it's complete but requiring less events (like WebStorage did). And also asynchronous events like a 'Request data' action and a 'On requested data ready' "scoped trigger" for when big data is necessary. This would make it possible to use both simultaneously, getting the benefit of both systems depending on the data you are dealing with. Like using synchronous events for simple values like lives and scores, and using asynchronous events for long data like dialogs or level data for custom level editors.

    *I'm assuming that in theory asynchronous events take the same amount of time to complete than synchronous, so it's possible to make synchronous events out of an underlying asynchronous system. If not then the change to an asynchronous system sounds much worst than I thought.

  • I think that the "Then" idea is only useful for cases that only requires a single value check like AJAX and Pathfinder. But for those cases I think the current system with custom conditions is more descriptive of what it does.

    For storage I would prefer to process groups or batches of values at once, otherwise it would be a PITA. Like setting together the X and Y of an object from LocalStorage in a single action, instead of storing the returned values in local vars as buffers:

    Sprite: Set position to ( LocalStorage.get("X") , LocalStorage.get("Y") )[/code:gg9jmxwm]
    
    I propose adding tags to each 'get item' action, like this:
    [code:gg9jmxwm]>Keyboard: On Space pressed
    -LocalStorage: Get item "PlayerX" under tags: "SpriteAttributes", "SpritePosition"
    -LocalStorage: Get item "PlayerY" under tags: "SpriteAttributes", "SpritePosition"
    -LocalStorage: Get item "PlayerHealth" under tags: "SpriteAttributes"
    -LocalStorage: Get item "PlayerShield" under tags: "SpriteAttributes"
    -LocalStorage: Get item "PlayerWeapon" under tags: "SpriteAttributes"[/code:gg9jmxwm]
    
    Then it would be possible to test both when all the items of a specific tag are ready, or when a single item is ready:
    [code:gg9jmxwm]>LocalStorage: On all items from tag "SpriteAttributes" ready
    -Sprite: set position to ( LocalStorage.get("PlayerX") , LocalStorage.get("PlayerY") )
    -Sprite: set variable "Health" to LocalStorage.get("PlayerHealth")
    -Sprite: set variable "Shield" to LocalStorage.get("PlayerShield")
    -Sprite: set variable "Weapon" to LocalStorage.get("PlayerWeapon")
    
    LocalStorage: On all items from tag "SpritePosition" ready
    -Sprite: set position to ( LocalStorage.get("PlayerX") , LocalStorage.get("PlayerY") )
    
    LocalStorage: On item "PlayerWeapon" ready
    -Sprite: set variable "Weapon" to LocalStorage.get("PlayerWeapon")
    [/code:gg9jmxwm]
    
    In my opinion this system can be more flexible and indicates more clearly what it does.
    I also think that renaming the 'LocalStorage' plugin to just 'Storage' would make things less verbose  without compromising the understanding of what it does.
    
    *Edit
    
    I thought a bit more and while the tag system can work, it would require to think and track different tags if you want to get the same values multiple times along an event sheet. Now I see that the "Then" proposal is all about a scoping system for asynchronous events to relate only to the events that called them (without the need to explicitly name them).
    
    I always felt the need for something like this when using timers, and yes, it would be useful for all kind of asynchronous events.
    
    @Ashley
    Why would the "Then" trigger only be able to have a single async action in the previous event? Couldn't it run like an 'all completed' for the previous event async actions, and use explicit key references in it's actions like my suggestion above? I think the use of 'LocalStorage.ItemValue' instead of an explicit reference like 'LocalStorage.get("PlayerWeapon")' is what it's limiting it. If you store all the loaded values in a buffer under the hood you could explicitly reference them all.
    
    Another thought is that since this is a problem of scope representation at hearth, maybe sub-events can be used somehow for an elegant solution. I'm not sure how, but it may be a possibility consistent with how local vars scope works.
  • You do not have permission to view this post

  • Yeah, you can't use anything besides a constant for loops, it's a limitation you have to deal with. The loops are unrolled when compiled, so it needs a well defined value.

    Like Rojo said, the only way to make it work properly is to compile the shader at runtime with a different constant, but C2 doesn't allow that.

    The trick you mentioned can work for convenience in some cases, but probably will impact performance at least in some hardwares.

    If you only need a limited number of different values for the loop it's best to make multiple shaders with different preset constants. It's very inelegant and inconvenient, but it's what we have now.

  • You do not have permission to view this post

  • You do not have permission to view this post

  • You do not have permission to view this post

  • You do not have permission to view this post

  • You do not have permission to view this post

  • You do not have permission to view this post

  • Amen to that! Finally someone gets it!

    I recommend posting a minimal repro capx as example if you find glitches like these, otherwise is hard for someone to know if it's really a bug. There's too much variables involved, and sometimes depending how it is setup it doesn't show up (like this time). I tested your shader and it worked as expected initially. But it needs a different stack order to manifest.

    Huh, you also have a drop shadow Shader? Or it hasn't been published?

    I have dozens of shaders that I did to myself but I never published (except for Alpha Threshold and old CC effects). Most of them still needs proper descriptions for parameters, some code clean up to remove commented junk, and proper usage examples. Like I said in another topic, I intend to publish them sometime but I never find the time to do it. Someday perhaps...

  • I see now, I get the same glitched results. It's strange that the problem only occurs at a specific stack order.

    But it's definitely a bug. Now I understand why one of my drop shadow shaders behaves weirdly when I change the opacity of an object or layer it's applied to. It's probably related to the problem you depicted in the other topic.

    My guess is that it happens in C2's compositor. Maybe it can be an overlook caused by some kind of render optimization (?).

    I have a very recent Nvidia card with up to date drivers, so there's only a very small chance of being a driver's bug.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
Animmaniac's avatar

Animmaniac

Member since 18 Mar, 2010

Twitter
Animmaniac has 1 followers

Trophy Case

  • 14-Year Club

Progress

14/44
How to earn trophies