0 Favourites

Hypothetical Event system redesign.

  • Here I present an idea for a ground up re-design of Construct's event system. This is purely for the logic portion and doesn't cover engine features. It's not entirely fleshed out and there are details I'm probably forgetting. The purpose is purely for fun, and may never see the light of day.

    conditions

    First off conditions are greatly simplified.

    Here are the system conditions:

    * "if" which is basically the same as system->compare

    * "else" this will differ from C2's else in that it doesn't pick, it's only if the previous event block was false.

    * "loop" which will cover all looping: and will look like "loop: var i=0 to 10", "loop: var i=sprite.count",...etc. More on what "var" is later.

    * "split filter" my solution to else. It's like "filter" below but the unpicked instances will be put in another type. Example "split filter: sprite, sol other: sprite.x>0", after which "sprite" will be all the instances below 0 and "other" will be all the instances above zero.

    Object conditions will be:

    * "filter" which is the catch all picking. For example "sprite: filter sprite.x=2" will replace "sprite: pick by x=2". It still follows the rule if nothing is picked then the following conditions in the block don't run.

    "sort" the idea with this one is is an object type is a list of objects and can be sorted. The closest in C2 already is the for each ordered. One example use would be "sprite: sort sprite.y" which would sort the object list from low to high instead of it's current order.

    actions

    Actions as well will be simplified. Basically for values, instead of "sprite: set x to 10" it would be "sprite.x=10". More on other kinds of actions later.

    variables

    Next up are variables definitions. The big thing here is you can put them anywhere you need them. A list of possible places:

    * in between event blocks, like C2 already does

    * inside event blocks

    * in the actions column.

    * special cases: var in "loop", and sol in "split filter".

    Next we have two kinds of variables:

    * "var" this is basically the same as C2's variables. aka. number and text. However this can be extended to array, object, dictionary, etc...

    * "sol" this defines a new type on the fly, which will replace families and make picking two seperate instances simpler. From the point it's defined it acts like any other object type.

    Family example:

    sol family=sprite, sprite2, sprite3
    
    +----------------------------+
    | family: filter family.x<10 | family.x = family.x+1
    +----------------------------+[/code:3j88tc5m]
    
    General picking example:
    [code:3j88tc5m]+----------------------------+
    | sol other= sprite          | sprite.x=200
    | sprite: filter sprite.x=10 | other.x = 11
    | other: filter other.x=11   |
    +----------------------------+[/code:3j88tc5m]
    
    [b]expressions[/b]
    Referencing seperate instances with expressions will be improved.
    You can still do the familiar pattern for an action: "sptite.x = sprite.x+1" which will add 1 to the x of every picked instance.
    You can also use "sprite[0].x" which is about the same as c2's "sprite(0).x" but will reference the first picked instance of sprite instead of just the first instance. You can also do stuff like this:
    x of first picked sprite: "sprite[0].x"  
    x of last picked sprite: "sprite[-1].x"
    It even applies to the action:
    [code:3j88tc5m]+----------------------------+
    | sprite: filter sprite.x<10 | sprite[0].x = 11
    |                            | sprite[-1].x = 22
    +----------------------------+[/code:3j88tc5m]
    Also objects can be assigned to variables.
    [code:3j88tc5m]+----------------------------+
    | start of layout            | sprite.child = sprite2
    +----------------------------+
    +----------------------------+
    | sprite: filter sprite.x<10 | sprite.child.y = 11
    +----------------------------+[/code:3j88tc5m]
    Another reason for this is to make create an expression if you don't want to affect the sol:
    [code:3j88tc5m]+----------------------------+
    | start of layout            | var new = create("sprite")
    |                            | new.x =33
    +----------------------------+[/code:3j88tc5m]
    Of course you can use create as normal as well which only picks that new sprite. At this time of design the same top level picking as with C2 is used.
    [code:3j88tc5m]+----------------------------+
    | start of layout            | create("sprite")
    |                            | sprite.x =33
    +----------------------------+[/code:3j88tc5m]
    
    [b]Functions[/b]
    This is the most significant re-design.  The goal is to make functions be able to be used perfectly as a condition, action or expression.
    
    First off parameters are named and can be object types.
    
    [code:3j88tc5m]+-----------------------------+
    | on function "turn" (ot, deg)| ot.angle = ot.angle+deg
    +-----------------------------+
    +-----------------------------+
    | start of layout             | call turn (sprite, 90)
    |                             | call turn (sprite2, 45)
    +-----------------------------+[/code:3j88tc5m]
    
    Next the return action will actually exit the function instead of just setting the return value.
    [code:3j88tc5m]+-----------------------------+
    | on function "dist" (a, b)   | return distance(a.x,a.y,b.x,b.y)
    +-----------------------------+
    +-----------------------------+
    | start of layout             | sprite.width=call.dist(sprite1, sprite2)
    +-----------------------------+[/code:3j88tc5m]
    
    Next in order for a function to modify a sol, returnSol is used instead.  This allows it to be used as a condition.  ReturnSol can have multiple values.
    
    [code:3j88tc5m]+-------------------------------------+
    | on function "indist" (a, x,y,dist)  | returnSol a
    | a: filter distance(a.x,a.y,x,y)<dist|
    +-------------------------------------+
    +-------------------------------------+
    | call "in dist"(sprite, 0,0,100)     | sprite.angle = sprite.angle+1
    +-------------------------------------+[/code:3j88tc5m]
    
    The synatax of calling sould simplified somehow.  Above are just a few ideas.
    
    Anyways that's a rough overview.  I'll have to prototype it in order to flesh out a few of the details.
  • These ideas are interesting. I see some useful stuff in it.

    I sometimes use c2's Picking with c2's Else.. so that, if there is nothing picked (it can't find a match), it will run specific events.

    How would that be accomplished in your case here?

  • Prominent

    In that case "else" would still work since it's just logic based. Aka the else will be true if the previous event block fails. It just doesn't do any picking. The "split filter" condition is supposed to address the else like picking, but I may yet axe it from the design since it's kind of akward. I'm shooting for simple and intuitive with everything.

  • Construct 3

    Buy Construct 3

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

    Buy Now Construct 3 users don't see these ads
  • There are some interesting ideas in there, but it reads to me like moving 75% of the way towards just being a programming language. Also I think making the sol/filtering stuff explicit makes it a lot less beginner friendly - it's supposed to basically be invisible and "just work" from a new user's point of view.

  • Ashely

    I'd agree there about it being more like a programming language, which doesn't necessarily make it harder for a beginner. It's kind of more event sheet inspired at this point.

    The "filter" condition would act just like the "pick by comparison" condition of c2, it could be called "pick" as well but for now I'm leaving it for now. The idea for "sol" is it would be a more advanced feature to allow some additional control. Without it things would operate the same as most of C2's events already do.

  • Hope i am allowed to steal this post to propose an other idea. I would like to have a system object in the form of a library holding the Selected Object List. Yes a library with no duplicate keys allowed. This object (a special library object) would be possible to add to the layout more then one time. The object should have 3 properties.

    1/ key: a dropdown list with usefull keys. As IID, UID, etc. (no duplicates allowed)

    2/ value: a dropdown list with usefull values. As IID, name, UID, instance variable,x,y,w,h, .... even none

    3/ filter: all objects, certain object, all but a certain object.

    Conditions as in the existing library object,

    actions as in the existing libray, except the actions that change keys/values. Plus actions like:

    • Is a key changed.
    • Is a value changed
    • Is count changed

    Just a wild idea.

  • 99Instances2Go

    I can't visualize the idea. It seems kind of non-intuitive. I'd have to see it in action.

  • A bit/kinda/sorta like this:

    https://

    drive.google.com/open?id=0B1SSuCVV8v74c2kwQmVtbXNLYWs

    Buggy as hell and Just 4u to visualize.

    And i meant a Dictonary alike system object holding ALL the Selected Objects List, with preconfigured filters. Not 'library'. Mea Culpa. I apologize for that.

    Run in debug to watch the Dictionary. Its the Dictonary that tells the story.

    (and now i speak directly to you, thx for all the things i learned from you)

  • 99Instances2Go

    I think normal picking works well for that sort of thing already.

    I do think it could be handy to be able to save a copy of the list of picked objects to a variable, but there are issues when objects can be destroyed.

  • Very interesting topic.

    There's some ideas that could (and in my opinion should) already be applied to the current event system. Like the possibility to define variables inside event blocks or actions, reference instances by the order of picking, and be able to name function's parameters. I already felt the need for these before and totally endorse them.

    I also really like the idea of creating temporary families inside the code. This could be extremely useful to use with functions and make more modular events.

    Also the possibility to save the SOL to variables is one of my dreams. Being able to pre-process a SOL, store it, and later load it again could help save some serious processing when dealing with a lot of instances and expensive filters. There's some cases where you need to repeat the exact same complex picking at a later time, plus some different conditions, that could be seriously optimized with this. Instead of checking collision, plus position, plus variables, plus n other things... for thousands of instances repeated times, you just compute it once and store it, then load it when needed. Most certainly just manipulating a list should be a lot faster than to compute everything again.

    One thing that I noticed is that your proposal works easily with typed code, but do you have thought in how it would work with the event wizard?

    For instance, since the actions don't seem to show an explicit object type like conditions do ("sprite: ..." or "system: ..." ), I imagine they would be a generic editbox where you type actions as expressions, am I right? That works well for setting variables, but how about other actions that depends on dropdowns with options and the like? Or things that are very specific to an object type?

    Also here the "a" is only referenced inside the function but appear as an object type in the condition below. To place the second condition, would it show on the objects list like local variables do, or the idea is to have a generic editbox for the object type as well?

    +-------------------------------------+
    | on function "indist" (a, x,y,dist)  | returnSol a
    | a: filter distance(a.x,a.y,x,y)<dist|
    +-------------------------------------+[/code:2711oo0f]
  • Animmaniac

    I haven't given a whole lot of thought how the event wizard would work with the design. Right now the design is like typed code to show what you can do. Things to help you do it would come later. Ideally though if you had an action like:

    Sprite.setPositionTo(sprite2)

    You could click on sprite2 and it would give a list of objects.

    In fact actions and conditions could be added in the same way as you can now in c2. Expressions are the main thing that is being revamped.

    In that function "a" is replaced with whatever object type you call the function with. So if you called it like this:

    Call indist (sprite, 100,100,50)

    "a" would be Sprite. It's basically another way to make things more generic.

  • How about inline vectors?

    OK yeah, I know...

  • In that function "a" is replaced with whatever object type you call the function with. So if you called it like this:

    Call indist (sprite, 100,100,50)

    "a" would be Sprite. It's basically another way to make things more generic.

    Yeah, that part I get it and would be very useful. My main doubt is how to make this viable.

    From my perspective, in order to make it work the "a" would need to be a sol variable previously defined and limited to only one object type, in this case "Sprite".

    Otherwise you could call "indist(sprite, 100,100,50)" or "indist(tiledBG, 100,100,50)", two different object types with different specific conditions. So when placing the condition you would need to select the condition inside a list of an object "a", of the type "sprite", that would temporarily appear into the object list (like local variables do). If not, how would you deal with different object types that have specific conditions not present in other object types? Like you could call both a sprite or a tiledBG, but they don't have the exact same condition set (like "animation is playing" for instance).

    Unless all the object types have a common subset of conditions (like position, size, opacity...) and you can only use these when picking an object through a variable (like "a"), and select them through the system object.

    *Actually I have some ideas for families with multiple object types that probably could help with this. When I get more time I'll post them.

    How about inline vectors?

    OK yeah, I know...

    Well remembered. It's something that would be great if could be incorporated.

  • SOL could be treated as a set of UID.

    I had made a plugin named instance group before, it stores instances by UID in a dictionary structure for set operation, and it also has another array structure for sorting.

    Maybe scirra could provide a similar plugin officially, with more powerful features.

  • rexrainbow

    We all know the main annoyances. (I did not use the word problem)

    1/ The Forum is filled with poeple asking for assistance with de Selected Objects List.

    2/ Most beginners (including myself) have a hard time with understanding the relation between subevents and a previous made Selected Objects List.

    3/ Most beginners (including myself) seem to have troubles with visualizing the Selected Objects List after a pickevent and wich objects will be passed to the actions.

    4/ Most beginners (including myself) seem not to understand the difference, in relation to picking, between system based comparing and object based comparing.

    5/ Most skilled forum mumbers seem as they gave up on answering the same question over an over again.

    This is a very good example: forum/is-this-a-bug-in-construct-with-or-statements_t170213?start=10

    Its is my sincere understanding that those annoyances can be solved by a (optional: you bring it in the layout or not) dictonary holding the SOL. Debugging would be a lot easyer for beginners. The learn curve would be a lot flatter. And it can be a big help with advanced picking.

    I know that this is totaly no issue for the skilled people. But. Think back at your first days with Construct. Even when that were the Classic Version days (like in my case).

    Hope i made my point, not gooing to nag more about it though.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)
Similar Topics Posts Views Last Post
Unread hot topic
234 61,207
DARKSETH's avatar
DARKSETH
Unread hot topic
90 13,970
liamdawe's avatar
liamdawe
Unread hot topic
152 19,223
Magistross's avatar
Magistross