User Tag List

Page 3 of 3 FirstFirst 1 2 3
Results 21 to 25 of 25

Thread: Best way for a frame-based level editor in CTF 2.5+ ?

  1. #21
    Clicker Fusion 2.5 (Steam)Fusion 2.5+ DLC (Steam)

    Join Date
    Aug 2010
    Location
    Sweden
    Posts
    87
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by zip2kx View Post
    Here you go: https://community.clickteam.com/threads/84185-Array-Level-Builder-for-Fusion-2-5-(variation-on-Shawn-s-example-of-the-same-name)

    This is pretty much the optimal way of doing it. Basically you create seperate levels and then save them to a different Z position in an array. Then you have a Game Frame which houses all of your events and then you load the correct Z position for whatever you need.

    With that said, 2.5+ improved its Global Events so it's realistically possible now to have individual frames as levels and the engine in Global Events.
    I tried the example from the 2.5 version, although I'm locked from testing the 2.5b version which seems to be better optimized. This is because the file has the "JoystickControl.mfx" extension.
    The 2.5 version seems really good, but my main gripe with the 2.5 version is the inclusion of line "Write to String aActiveObjectName( "Group.Engine" ) to aId ( " Group.Engine"), 0". This is mainly because the string must be exacty the same name as the active object for the save/load-system to work. The idea of having to do this for a thousand different objects seems like a big drawback for me.

    Do you have the 2.5b version without the "JoystickControl.mfx" extension built into the file?
    If not, do you know any way to fix this without having to rename/use the String?

    I'll attach a simplified version of the file as I don't need to save into an array which layer or object type the objects have.
    Attached files Attached files

  2. #22
    Clicker Fusion 2.5 (Steam)Fusion 2.5+ DLC (Steam)

    Join Date
    Aug 2010
    Location
    Sweden
    Posts
    87
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    I found out how to do it. It was very simple, I just seem to have missed it completely when I checked the first time!
    Uploading working file for reference.

    What has changed since the last file is that I wrote "OName$( "Group.Engine" )" instead of the String name. So now any object can have any name and defining the string name in every object is not necessary.
    Attached files Attached files

  3. #23
    Clicker Fusion 2.5 (Steam)Fusion 2.5+ DLC (Steam)

    Join Date
    Aug 2010
    Location
    Sweden
    Posts
    87
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    I think I now understand how to save and load all the essential things I need from the Array object.

    However, loading from the Array object seems very slow (or perhaps the slowness is because I do things wrong).
    Everytime I'm trying to load a section of the map at runtime (everything from 100-3000+ active objects at a time) the game freezes for a second which destroys the gameplay immersion.

    The reason behind my large map is that I'm trying to make a Metroidvania map which is way larger than my usual maps.

    Perhaps the way I'm doing things now is suboptimal as I also have to save parts of the level in different arrays for this to work?
    I guess that something simpler could be possible rather than splitting and saving a large map into five different arrays?

    I'm wondering if there is some better way of loading active objects from the array object that does not make the game stutter/freeze when the loading happens?
    Since I have all the active objects X and Y cordinates saved, perhaps there is a way to load them individually and only when the player character is in a certain distance to these positions? I have no idea how to make this though... Anyone done anything like this and/or have any directions for me?

  4. #24
    Clicker Fusion 2.5 (Steam)Fusion 2.5 Developer (Steam)Fusion 2.5+ DLC (Steam)Android Export Module (Steam)HTML5 Export Module (Steam)iOS Export Module (Steam)Universal Windows Platform Export Module (Steam)
    Volnaiskra's Avatar
    Join Date
    Jan 2014
    Location
    www.sprykegame.com
    Posts
    2,269
    Mentioned
    89 Post(s)
    Tagged
    0 Thread(s)
    I haven't looked closely at your MFA, and there might be various things you can do. But I have one suggestion:

    Your arrays use strings, which are inherently slow. One option would be to somehow combine 2 arrays - a value-based array for X & Y, and a string-based array for the object name. It might be a little tricky to coordinate these at save time so that each index of the arrays relate to the same object, but it should be doable. If you did this, your fastloop would only have to read 1 string (and 2 values) each iteration, rather than 3 strings. This would probably speed things up a bit.

    Another option is to use only a value-based array. This is faster still, but it introduces an annoyance when it comes to naming the objects. It's the way I do it, and it works for me. Mind you, it still takes a moment to load and would probably still involve some stutter if you did it mid-game (I only load the level at the beginning so in my case it doesn't matter). But it's sure to be faster than doing everything with strings.

    Here's a very simple and fast way to do it, but also the most annoying in terms of naming, because you have to name all your objects "1", "2", "3", etc. instead of friendly names like "grass 1", "grass 2", etc: (btw the green rectangle icon is my "platforms" custom qualifier icon...just like your group.Engine one)



    If you're fine with having just numbers as names, then this method is probably the fastest way you can do it - at least as far as I know. There are probably other things you can do to optimise the process (maybe not using 5 arrays, maybe staggering how you load them rather than all at once, maybe some other stuff...I don't know). But in terms of the actual reading of the array, using values will be faster than strings, and probably noticeably so. Below, I give you some more detail into the way my own method has evolved over the years, in case you or other readers are interested, though it's a little more complicated, and not quite as performant as using strictly numbered objects.



    ⸺⸺⸺⸺⸺⸺⸺⸺⸺⸺⸺⸺⸺⸺⸺⸺⸺⸺⸺⸺⸺⸺⸺⸺



    If it's too unwieldly to have your objects named purely with numbers, then there are other things you can do. This will add some more complication to your code (but it will add simplification to your workflow, since you can use semi-normal object names). What I do is I group my objects into 'types'. So, for example, my decoration types are called "deco1", "deco2, "deco3" etc. and my platform types are called "P1", "P2", "P3" etc. Your current MFA already has more or less that naming convention - so let's say that you want "grass1", "grass2", "grass3", and "block1", "block2", "block3". You could then add another value to your array that you can think of as "type", which tells it which 'type' an object is from. Let's say "grass" tiles are 123 and "block" tiles are 8. Then you'd do this at load time:



    This has the added benefit that you can run different actions on different types of objects, which you may end up wanting, as your game gets more complex. For example, you might want your "grass" objects to just be placed at X & Y, but you might eventually want to load in an "enemy" object that you position at X & Y and change its direction (but you don't want to change the direction for all objects like the grass - just the enemies).

    Now, if you do it this way, you'll probably end up with quite a few events: one for grass (aka 123), one for blocks (aka 8), one for doors, one for lamposts, etc. etc. You'll end up with a lot of wasted time where Fusion is checking things it doesn't need to. Let's say that the array is currently loading a grass object. Fusion will first do 'is this type 123 (aka grass)?"....yes it is...what is its name, X, and Y?.....then onto the next event....is this type 8 (aka block)?....no it's not....onto the next event....is this type 9 (aka lamppost)?...no it's not.....etc.

    Once Fusion has successfully loaded a grass object, it would be great if the loop could just stop, and go straight to the next iteration. But there's no way of doing that directly. Even if you do "stop loop", it still will check every "on loop" event in the frame before it stops. There is a way you can do this though, with a workaround. It involves placing the fastloop inside a group, and then deactivating that group once you want to quit the fastloop. When the group is deactivated, the fastloop will immediately terminate. Though of course you don't want it to terminate, but to keep going with the next iteration. So below is how I do it. It's just a screengrab of some of my code and comments - I hope it makes sense. It involves using 2 fastloops: a parent loop (that will run as many times as there are objects) and a child loop (that will also be run each time, but it will only ever run one iteration then be aborted....so its loopindex will always be 0, which makes its loopindex useless). We also need a way to transfer information from one loop to the other, so we use alterable values for that. Notice that we also read information from the array only once per iteration, and store it in alterable values, with all subsequent events reading from the alterable values. This is because it's faster to read from alterable values than from arrays.


    So here's a screengrab of some of my code, where it sets up and runs the fastloops, including the loading code for several of my object types:



  5. #25
    Clicker Fusion 2.5 (Steam)Fusion 2.5+ DLC (Steam)

    Join Date
    Aug 2010
    Location
    Sweden
    Posts
    87
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the great answer Vol!

    I'll have to look into that more carefully when I get home. Especially the part about only using numbers instead of strings to optimize things.


    I have found a way to decrease the saving/loading time by an extreme margin. I had failed to understand that when I copied the array from the previous example it had the X/Y/Z dimension of 512/5/100. I decreased these to 0/0/0 and that reduced the saving time to basically 0 seconds. The loading time is just a small stutter now as well. The .arr files has also decreased in size from around 20MB to around 200 KB each.

    Perhaps this can be optimized further by setting the initial dimensions to the dimensions that will be used instead of 0/0/0 which has to increase itself?

    I use the following dimension:
    Str$(NObjects( "Group.Engine" )) @ 0,0
    OName$( "Group.Engine" ) @ ID of Group.Engine, 0
    Str$(X( "Group.Engine" )) @ ID of Group.Engine, 1
    Str$(Y( "Group.Engine" )) @ ID of Group.Engine, 2

    I guess this would result in an array dimension of 3/2/0 (First @ 0,0. Second @ 1,0. Third @ 1,1. Fourth @ 1,2)?
    I don't know if this is corrects as the X index isn't a number but the ID of the Group.Engine in the last three strings.


    However, I'm still using both X and Y dimensions in my array.
    Would it be more optimized and faster to only use the X index as that dimension would be 4/0/0? Is this even possible?

    I tried to do this. But while StrAtXY( "Array", LoopIndex("LOAD"), 0 ) is a valid expression, StrAtX( "Array", LoopIndex("LOAD"), 0 ) isn't. The expression window tells me that a bracket is missing just before the LoopIndex which isn't true?

Page 3 of 3 FirstFirst 1 2 3

Similar Threads

  1. Object frame to Level Editor on sale right now!
    By PandaExplosion in forum WIP & Released Games & Apps
    Replies: 2
    Last Post: 15th July 2019, 05:07 PM
  2. Level load - Change frame based on position
    By Vetmora in forum Fusion 2.5
    Replies: 6
    Last Post: 14th June 2018, 08:05 AM
  3. Level editor that uses MMF2's own frame editor
    By Shawn in forum File Archive
    Replies: 35
    Last Post: 9th November 2013, 07:34 PM
  4. Tile-based level editor
    By Gabriel in forum File Archive
    Replies: 9
    Last Post: 7th March 2007, 09:17 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •