dop2000's Forum Posts

  • Can’t it just be reported as a bug so it gets fixed? Seems like an oversight that space gets reserved for the biggest we’ve resized a tilemap instead of only storing the visible ones used.

    This is definitely an oversight, but Ashley will probably argue that not all tilemaps can be safely cropped. What if you resized it by mistake? Or maybe you keep a large tilemap shrunk in the editor to save space, and only resize it to its full size when needed?

    I was just about to start as project with tilemap size of 98304 x 98304 tiles

    If my math is correct, this will use about 400 GB of RAM :)

  • Sorry for the clickbait title, but if you’re using tilemaps in your projects, or you’ve ever had the editor crash with an out-of-memory error - you really should read this. TL;DR at the end.

    The problem

    You may have noticed that tilemaps remember their previous size. That kinda makes sense: if you shrink a tilemap and later make it bigger again, the tiles aren’t erased - they’re still there.

    But now imagine these scenarios:

    1. You have a large open-world layout, say 20,000×20,000 pixels, and you add a new Tilemap object. By default, the tilemap takes up the entire layout, so its size becomes 20,000×20,000. You then resize it to what you actually need - say 300×200 - and think nothing of it.
    2. You have a fairly large tilemap, maybe 3200×3200, and you want to reduce the tile size from 32 px to 16 px. But instead of typing 16×16, you accidentally enter 1×1. Oops. You notice the mistake, change it to 16×16, and move on. No harm done, right?

    Wrong.

    In both cases, the tilemap will now forever remember its maximum size.

    Tilemap #1 is now 20,000 / 32 = 625 × 625 tiles

    Tilemap #2 is a staggering 3200 × 3200 tiles - tiles, not pixels!

    Why is this bad?

    Browsers have a hard memory limit per tab. In Chromium-based browsers it’s about 4 GB. That means the Construct 3 editor - including all its modules and your loaded project - must fit within that limit.

    Now let’s see how much memory our “rogue” tilemaps consume:

    A tiny tilemap #1 with a visible size of 300×200 px takes 15 MB of RAM.

    And that’s per instance. If you copy that tilemap to 100 layouts, that’s 1.5 GB - over a third of the total allowed memory.

    Tilemap #2 uses 410 MB. That’s 10% of the entire memory budget. Duplicate it once? Boom - another 410 MB gone.

    It doesn’t matter if the instances are on different layouts — the editor loads all tilemaps from all layouts into memory.

    And eventually this happens:

    There is a bit of good news: it seems that invisible areas that are completely empty (tileID = -1) don’t get loaded into memory. Unfortunately, the moment you use the Bucket tool, those areas get filled with tiles — and now they do count.

    Real-life implications

    “But those are unrealistic scenarios” you might say.

    Ha. Let me tell you a sad story.

    While working on our game, I’ve been dealing with random “Out of memory” crashes for years. I upgraded RAM multiple times, tried every Chrome flag imaginable, switched to Edge and Brave — nothing helped.

    Our project sits at around 3.5 GB of memory usage, right on the edge. Any sudden spike (for example, running a big search) can push it past 4 GB and crash the tab.

    We use tilemaps a lot. Just one example: we have 30 dungeons, each built from lots of small tilemaps (rooms). Each tilemap’s visible size is 40 × 22 tiles, but their maximum (invisible) size was 335 × 138.

    I honestly don’t remember how this happened. Maybe originally we planned one big tilemap per dungeon and later resized it down to single rooms. But Construct remembered the original size forever.

    I’ll spare you the math, but that’s ~20 million invisible dungeon tiles just sitting in memory, wasting RAM and CPU.

    Yesterday I ran a script that updated all tilemaps across all layouts.

    It processed 560 tilemaps and removed 98796127 tiles. 99 MILLION. Freeing almost 3 GB of RAM.

    No more crashes. And the editor runs a lot smoother.

    Important note: this applies only to the editor. In exported projects, invisible tiles don’t matter nearly as much — they will probably increase memory usage and save size, but won’t crash your game.

    What this means for you

    Check your tilemaps, people.

    Here is the script that automatically resizes tilemaps to their visible size. (requires NWjs for batch mode). Use it at your own risk, and please back up your project first.

    EDIT: R0J0hound made a much better version, use that instead.

    TL;DR

    Tilemaps in Construct remember their maximum size, even after you resize them. This means a tiny-looking tilemap can secretly contain millions of invisible tiles, eating huge amounts of RAM in the editor. Since browsers have a ~4 GB memory limit per tab, this can cause random “Out of memory” crashes. Check your tilemaps and make sure their max size matches what you actually use.

    Tagged:

  • Can you share your project file? The quality of the video you posted is quite low and all code is in Spanish..

  • loopindex expression doesn't work in "For each entry" loop. You can use "Compare value" condition with a relative path.

    JSON For each entry in "screens"
    JSON Compare value ".id" = nextScreen
    

    Since each screen has a unique ID, it may be easier to change JSON structure to this:

    {
     "screens": {
     "screen_1": {
     "elements": [
     {
     "type": "text",
     "id": "instructions",
     "content": "Screen 1 flashing section egestas."
     }
     ]
     },
     "screen_2": {
     "elements": [
     {
     "type": "text",
     "id": "instructions",
     "content": "Screen 2 flashing section egestas."
     }
     ]
     },
     "screen_3": {
     "elements": [
     {
     "type": "text",
     "id": "instructions",
     "content": "Screen 3 flashing section egestas."
     }
     ]
     }
     }
    }
    

    This will allow to access any screen directly, without looping through the entire JSON. For example:

    JSON.Get("screens." & nextscreen & ".elements.0.content")

    .

    Also, if each screen has only a single element - get rid of the arrays of elements, this will make it even simpler:

    {
     "screens": {
     "screen_1": {
     "element_type": "text",
     "element_id": "instructions",
     "element_content": "Screen 1 flashing section egestas."
     },
     "screen_2": {
     "element_type": "text",
     "element_id": "instructions",
     "element_content": "Screen 2 flashing section egestas."
     },
     "screen_3": {
     "element_type": "text",
     "element_id": "instructions",
     "element_content": "Screen 3 flashing section egestas."
     }
     }
    }
    

    Usage:

    JSON.Get("screens." & nextscreen & ".element_content")

  • You can use the TagAtPosition expression and then run the corresponding function for each tag. Or you can look up that tag in an array/dictionary/JSON to retrieve any additional information associated with it.

    + Mouse: On Left button Clicked on SpriteFont
     | Local string tag‎ = 
    ----+ (no conditions)
    -----> System: Set tag to SpriteFont.TagAtPosition(Mouse.X, Mouse.Y)
    
    ----+ System: tag = "foo"
    -----> Functions: Call Foo
    
    ----+ System: tag = "bar"
    -----> Functions: Call Bar
    
    
  • Does encapsulation cause performance degradation?

    I've heard people say that, but I wonder if that is actually the case.

    Yes, this did happen with the rollout of SDK2. The biggest issues were fixed, but there is still a small performance overhead, and in certain cases pre-SDK2 Construct releases can be a tiny bit faster.

    From what I understand, the SDK3 being discussed here applies to the editor API, so it shouldn’t affect runtime game performance. That said, there have been reports of the editor lagging or freezing for some devs. Here is one from just two weeks ago. It also runs out of memory on large projects. I really hope SDK3 encapsulation doesn’t make those issues worse.

  • Ashley Of course we value reliability, but we also want a capable and competitive game engine with strong support for addons. What would be the point of Construct if it began losing ground even to free engines like GDevelop?

    I've asked this question in the previous post: can you work with Skymen on safely integrating his (or a similar) API? Surely this would be a more productive use of time than developing SDKv3.

  • Huh, turns out that setting the animation speed on every tick makes the ping-pong animation to get stuck.. This is probably a bug, feel free to report it:

    github.com/Scirra/Construct-bugs/issues

    I made a minimal repro project:

    dropbox.com/scl/fi/tqm2htdpucls7t3hpr4h3/PingPongAnimationBug.c3p

  • Instead of "play from beginning" try "play from current frame".

    If that doesn't help, then there's probably some other event in your code that briefly changes the animation to a different one, which causes the "Climb" animation to restart.

  • Ashley, wouldn't it be a lot more productive to work with Skymen on properly integrating and safeguarding his API, rather than spending time and effort opposing it?

  • tileWidth and tileHeight are read-only in events too, you can't change them. You can probably prepare a bunch of tilemap templates with different tile sizes instead.

    mapWidth and mapHeight are calculated from the tilemap's width+height. Say, if the tile size is 16 and the tilemap width is 1600, then the mapWidth expression will return 100.

  • 1. Press F12 and check error messages in the browser console.

    2. Try clearing browser data.

    3. Try a different browser.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • You can try tweening a value, and setting the angle directly with this action:

    Car Tween "turnadjust" is running
     Car Set angle to self.Tween.value("turnadjust")
    
  • It's probably conflicting with the Car behavior - both are trying to control the angle.

  • If you have time, could you please port the EasyStarJS behavior?

    construct.net/en/make-games/addons/1140/easystar

    Thank you for doing this!