Animmaniac's Forum Posts

  • You do not have permission to view this post

  • There's a way to avoid the bleed. Put your tilemap on a layer, place another tilemap over it with the color masks and apply the effect to it. Then enable "Force Own Texture" to the layer.

    Here's an example.

  • The easiest way to do this is to create a new layer containing the color areas, then apply a modified version of the effect to function as a "mask" shader (it uses the layer texture to modify the background). It's quite easy to do.

    Just for curiosity, what's your use case?

  • You do not have permission to view this post

  • Animmaniac: The UID is already visible in the properties for any selected instance of most non global plugins in the editor.

    Yeah, but only when selected and not very visible among other information. The idea is to have it visible at all times in the editor. A small blue box at the corner of the bounding box so you can see it at a glance without the need to fight layers to select an object.

  • Since you are now an expert at edit side rendering, how about a simple behavior that displays the UID and/or IID of objects in the editor so you can more easily reference them in code?

    I don't know how feasible is to render text in the editor, but if it's possible this would be very useful for trigger zones, managing multiple cameras, dummy colliders and the like. If it had a field for a custom ID that you could set like "cam01", "triggerZone02", etc... that was displayed in the editor and could be referenced like a variable in events it would be supper handy as well. Other ideas are the ability to display the collision polygon per object, bounding box, hotspot, angle, and action points.

    It would be basically a helper behavior.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • 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