VictoryRice's Forum Posts

  • 12 posts

    Launch external editor doesn't work for me, it just spins eventually returns control after a minute or so. It works for me in the desktop build though.

    We're launching a beta of Construct 3 for Windows 10 in the Microsoft Store! This is an alternative to the NW.js-based desktop build.

    The C3 Store app requires the latest version of Windows 10 - the April 2018 update, build 17134+. This is already rolling out widely. Check Windows Update for any updates if you don't have it yet.

    How to get it

    Click here to open the Store page for Construct 3. Alternatively just open the Store app and search for Construct 3.

    As with loading editor.construct.net in the browser, you must be online the first time you load Construct 3. From then on, it will work offline. You can use your account offline for up to 7 days, but you must go online at least once every 7 days to renew the account. This is all identical to how offline support and accounts work in the browser.

    Features specific to the C3 Store app

    Architecturally the Store app is very similar to the NW.js desktop build. It enables new features using new WinRT APIs available to Store apps, instead of the Node APIs used in NW.js. In many places the code is identical but the implementation just uses a different API behind the scenes. So in terms of features it's pretty close to the NW.js version. There are only some differences where WinRT can't substitute something that Node can do, usually for security reasons.

    • You can save and load folder-based projects. This allows faster saves for large projects, and works better with source control.
    • Single-file projects (.c3p files) can be saved anywhere on disk.
    • You can copy and paste images in the Animations Editor.
    • The Animations Editor can launch an external image editor.
    • You can export a project directly to a folder on disk, rather than as a zip file.
    • It automatically registers a file type association for .c3p and .c3proj files, so you can double-click files to open them.
    • The C3 Store app also supports x86 (32-bit) and ARM versions of Windows as well as x64 (64-bit), whereas the NW.js build currently only supports x64.

    If you don't need any of these features, you can just keep using Construct 3 from the web. You can still create a desktop icon and run without the address bar from Chrome using the "Add to desktop" feature. There's more information in the manual.

    Known issues

    • Currently only the beta version of Construct 3 is supported.
    • You cannot purchase Construct 3 from the Store app. If all goes well we intend to add support for this later down the line. If you've already got a subscription, you can still log in and use it in the Store app.
    • Opening an external editor from the Animations Editor only has a single button which makes Windows prompt for which image editor to use. This is the best we can do with the available WinRT features. (For security reasons the app cannot launch a given EXE file.)
    • Store apps on Windows 10 use the Microsoft Edge browser engine, whereas the NW.js-based desktop app uses the Chromium browser engine. Edge is not as fast as Chrome so in some cases performance may not be as good as Chrome or the NW.js desktop app.

    FAQ

    Where do I download the C3 Windows 10 Store app?

    Click here or search for Construct 3 in the Store app.

    How do I update Construct 3?

    Currently the Store app serves the same version of C3 that appears at editor.construct.net/beta. It updates the same way as in the browser: you'll see a notification there's a new version available, and reloading the app will use it.

    Where do I report issues?

    The same place as any other C3 issues, on the GitHub tracker: https://github.com/Scirra/Construct-3-bugs/issues
    There is a 'desktop' tag we'll apply to issues relating to the desktop apps.

    How does feature X work in the desktop build?

    If it's not mentioned above, the answer is "identically to how it does in Edge".

    Let us know!

    We're interested to know what you think about this and how it works for you. Let us know if you have any feedback!

  • Yes, I did a little test and it seems you're right, the order of the layouts in the project bar is the first thing the runtime uses ... it does not start by looking at the currently active layout as I previously wrote. When I set an instance in Layer A and an instance in Layer B to have different instance variable intial values, and then ran the debugger on Layout B with an event action to spawn a new instance on Layer B, it pulled the initial value from the instance on Layer A even though B was the active layout. This was with Layer A as the first layer in the hierarchy under the Layouts folder in the Project Bar. Dragging Layer B up to be first under Layouts changed the spawned instance to inherit initial instance variable values from the instance on Layer B.

    Therefore it would seem best practice is to make my first layer the non-playable "holding cell" for one of every object in the project, and set the default values of instance variables on those instances for how I want them to be throughout the project. I previously had my holding cell layout as the last layout.

    One small caveat to what you wrote, I found (at least in the C3 runtime) it is possible for spawned instances to use instance variable initial values from an existing instance that isn't the lowest UID on the applicable layout. I can make this happen in the editor by dragging instance 1, (with C3 assigning, say, UID 14), than dragging one more instance of the same object (assigning UID 15), then deleting instance with UID 14, then dragging a new instance back to the layout. The last instance will get assigned 14 since it was just freed up, but the editor remembers 15 as being the "first" instance on the layout since at one time it was the only instance. Spawned instances (in my testing) then take the initial values from the UID 15 instance and not the 14.

  • Well, it's true that when in the editor you add an instance of an object to the layout, and there are no instances of it yet on the layout, its instance variables will be assigned the default values specified in the project tree.

    But I've found once you add an instance to the layout in the editor, that first instance is treated as special -- further instances you add to the layout in the editor will take their instance variable values from this one, not from the project defaults for the object. Even those instances added to different layouts in the project will grab their values from the first instance.

    By contrast, it (seems) to work a little differently for objects created at runtime. I'm finding object instances created at runtime will take their initial values of instance variables from the first instance of that object on that same layout; if there are no instances on that layout, it will take its instance variable initial values from the first instance on another layout, though not necessarily from the first instance created--it seems to go through the layouts in a certain order (by when they were created?) and looking for the first instance on each. Some examples to illustrate what I see:

    - Project has layouts A, B, and C created in that order, and one Sprite object

    - Scenario 1: In editor, I first add 2 sprite instances to layout C, then 2 to B, then 2 more to A and change their instance variables to unique values

    - At runtime, I create a new instance of the sprite on layout A

    -- Result: new instance on layout A takes its instance variable initial values from those set for the first instance added to layout A in the editor

    - Scenario 2: In editor, I first add 2 sprite instances to layout C, then 2 to B, and none to A and change their instance variables to unique values

    - At runtime, I create a new instance of the sprite on layout A

    -- Result: new instance on layout A takes its instance variable initial values from those set for the first instance added to layout B -- even though I added instances to layout C first, there is some order through which C3 goes through the layers that happens to look at B first.

    - Scenario 3: In editor, I don't add any instances to any layouts

    - At runtime, I create a new instance of the sprite on layout A

    -- Result: C3 hangs because there must always be at least one instance of an object on at least one layout before using the System -> Create Object action. (Actually C2 runtime gives a helpful error message, C3 runtime just hangs on a black screen.) Notably, the runtime does not create the object and use the instance variable defaults set in the project tree.

    I was wrong (I think) about the UID order having anything to do with all this. There are probably more nuances as well so I'd love to hear the exact logic in use, so I know exactly what to expect when dynamically creating new object instances.

  • Can someone explain to me the rules determining how C3 assigns initial values to instance variables when creating an object at runtime with System -> Create Object?

    My observations:

    • If I've added only one instance to a layout (as C3 requires at least one), not surprisingly the new instance added at runtime takes on the initial values specified for that original object instance.
    • If I have two instances added to the layout in editor Layout View, each given different initial values for their instance variables, the third instance created at runtime takes on the initial values of one of the original two, but I don't know how C3 chooses. It seems like maybe it's the one with the lowest UID.
    • If in the editor Layout View I have one instance added to layout B with UID 10, and two instances added to layout A with UIDs 15 and 20, and at runtime I create a new instance on layout A, it seems like the initial values of instance variables are taken from the initial values of UID 15. (The lowest UID from the layout the new instance is created on, but not the lowest UID across all layouts.)
    • In the example above where instance with UID 15 is used as the template for initial values of instance variables on newly created instances, it doesn't seem to matter if instance UID 15 is destroyed prior to creating the new instance. Nor does changing the values of UID 15's instance variables at runtime prior to creating the new instance affect it -- the instance variable initial values for the new instance will come from whatever was input in the editor before running the layout.

    In the end what I'm looking for is 100% predictability on what the initial values of instance variables will be for instances created at runtime. I do wish each object had global default values that are independent of any instances added to the layout so I don't have to worry about which one is the lowest UID on the layout (if that is indeed how it works). But at least being clear on what's happening will help me plan accordingly.

  • Thank you! I'm not sure I would have figured this out on my own. To be honest, the documentation covering For Each is a little cryptic and I wasn't sure when I'd need to use it. I still had to think about it for a while after your post until it finally made sense.

  • Curious how others would solve what I'm trying to achieve. Let's say I have a Sprite object called Blue, with two instances on the layout.

    Blue #1 is overlapping only Red and Yellow Sprite objects.

    Blue #2 is overlapping only Yellow and Green Sprite objects.

    Overlapping any Red, Yellow, or Green causes Blue to "die," but with a different animation depending on which color "killed" it. In the case of Blue overlapping multiple colors, the priority is Red, then Yellow, then Green.

    So Blue #1 is considered to be killed by Red, and Blue #2 is considered to be killed by Yellow.

    I want to write event logic that, in plain English, does:

    • Pick Blues overlapping Red, play the "Death by Red" animation
    • For Blues not picked, pick Blues overlapping Yellow and play the "Death by Yellow" animation
    • For Blues still not picked, pick Blues overlapping Green and play the "Death by Green" animation

    In a conventional programming language I would iterate through every instance of Blue, and run each through a series of If Then - Else If - Else conditions. (Or Case - Switch.) And originally I thought I could use C3 Else conditions, but that was before I understood the Else condition is only met if the previous event didn't run for any instance of Blue -- if even one Blue is overlapping Red, my "Else If Overlapping Yellow" block won't run even for the Blues not overlapping Red. (I also misunderstood that Else doesn't pass through unpicked Blue instances from the previous Event -- all instances revert to unpicked.)

    I could add more conditions to each subsequent event, for example for the Yellow overlap test, I could say "Pick Blues that are not overlapping Red and are overlapping Yellow." And the next event could be "Pick Blues that are not overlapping Red and not overlapping Yellow and are overlapping Green". The disadvantage here is that in my real project, the conditions are considerably more complicated and there are many more events, so it would be very bulky--by the time I got to the last event, I would have a huge list of negative conditions to test for to make sure I'm only picking the instances not picked by one of the preceding Events.

    The best solution I can think of is to use an instance variable to flag when an instance has been dealt with -- in this case, "isKilled" or something ("Play Death by Red animation and set isKilled to True"). Then each subsequent event could exclude any instance who have isKilled = True.

    Is there a more natural way in C3 to handle this?

    (P.S.- My actual scenario is using Custom Movement to do elaborate testing for overlap at many different offsets to determine what action to take ... Often the Sprite will meet the conditions of more than one test so I have a priority order. And since many of those actions are Push Out of Solid, which immediately change the position of the Sprite, that movement then makes the Sprite meet the conditions of overlap tests below it. I was using Else blocks which worked fine when I had only one instance, but when scaling to multiple instances things went a bit crazy.)

  • Wondering for large projects with many sprites, what kind of workflows have people designed to go back and forth between engine and editor? (I'm a user of Cosmigo's excellent Pro Motion NG pixel art editor.)

    In my case, it's easy enough to export sprite strips from Pro Motion and import them to Construct 3's using the UI's animation editor, but it gets tedious every time I want to make a graphic change to existing animations. For one thing, re-importing a sprite strip destroys the collision polygons and frame durations, so I have to export each animation as separate images for each frame, then literally drag and drop each image into each existing frame in C3's animation editor. (No, I don't want to do these graphical changes in Construct as all my palettes, layers, and other project setup are in Pro Motion, and of course being a dedicated, full featured editor it just has better tools.)

    I don't know if it's possible or even a good idea to directly edit the sprite PNGs stored in the .c3p file with an external editor. The next best thing I could think of would be writing a custom script to take exports from the editor and replace the corresponding images within the .c3p file, though that seems risky. (Pro Motion does have a facility to trigger an executable upon export for this purpose.)

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • I agree the way Else logic is handled (as distinct Events) is a little unintuitive. I would prefer that they visually appear and act as attached to the events they are depending on above, both for visual understanding and also for when I'm dragging to reorder events. When reordering events, it's easy to forget to drag the Else event along with the event above it upon which it is logically dependent; or when dragging another event, it's easy to mistakenly insert it above an Else, separating it from the event it's meant to be directly underneath.

  • I would suggest either randomly generating the level, or creating it on the fly based on the data in an array (data you've either hard coded in, or loaded from a JSON or XML file). You can use the system action Create Object to create the level tiles off screen just before they need to scroll into view. Then you can destroy them when they're off screen.

    I'm pretty green when it comes to designing games, so I'm sure that some of the things that I say here will be kind of stupid, but I'm trying to design a map (outside of Construct) for a game that I wish to create which is what would be a 1/2 mile track in the real world. This game is of a squirrel running and jumping through trees. Squirrels run at burst speeds at 12 mph, and so I decided my squirrel would run an average of 6 miles an hour, deciding that my track needed to be a 1/2 mile long for 5 minutes of game play.

    I did a little math, finding that at 1080p on a 14 inch screen, a half mile track would be 7.2 million pixels long on a layout. I must say here that I don't really understand how to equate all of this at all. Anyway, I opened a project and set the layout size to 1080 x 7.2 million, and the layout came back sized 1082 x 1 million. So, I assume that Construct limits the layout width to 1 million pixels. Assuming this is true, how could I ever make such a track, which is essential to my game? Secondly, can a such a game be designed without crashing a computer? This game will be designed for computers, not mobile. It seems that for any sort of linear racing game, a track would need to be very long, so I feel that this shouldn't be a big deal, but my stumbling research appears to say otherwise.

    Thanks.

  • Thank you! I did not pick up from the docs/tutorials that I can have an action without an explicit condition in the same row.

  • What is the best form in Construct to accomplish the following?

    • Enter a subevent
    • Create a local variable for this scope, and initialize to the value of a global constant
    • Execute a loop, modifying the value of the local variable
    • After termination of the loop, reset the local variable to the value of the constant
    • Run a second loop that makes use of the local variable
    • Exit subevent

    I'm not allowed to supply the constant as the initializing value--only numeric literals are permitted it seems. And I'm not sure of the "proper" way to execute an action modifying the local variable before a loop begins (or after a loop exits, or between loops). The best I could come up with is to insert a couple of System > Every Tick rows, as per the sample code below. It works, but it feels kludgy, especially in the context below where this is "run once" code at the start of the layout, and not something that actually runs every tick. Do any experienced folks have some wisdom to share?

  • Is it possible to seed the random() function? There are cases where I'd like "random" behavior that is also deterministic (i.e., plays the same way every time). Another would be procedurally generated levels, where anyone can input the same seed to play the same level (a la Minecraft).

  • 12 posts