Feature Addition: "Room Object"

  • How would a layout persist behavior deal with multiple instances?

  • Ashley:

    Thanks for looking at my test.

    I tried to keep this succinct. I failed. I think it's good reading though.

    IMHO, C2 already does pretty well with large layouts...barring a few exceptions. Here's my thoughts on that:

    1. Example of real-world usage of large numbers of objects:

      a. A MMO, or open world RPG. A game like this could easily have many thousands of objects populating it's expanse. b. A Castlevania, Metroid, or Zelda style game with unbroken area/room transitions. c. A GTA style game. Yes, many objects in such a game are dynamically 'spawned in', but there are a plethora of props and unique structures. I must admit though...a game like this would probably run into image memory limitations before hitting object limits.

    2. Solutions:

      a. Managing large layouts:
      It seems like the best approach would be a version of what Tokinsom is suggesting: Load/Save/Reset/Void layout zone (x1,y1,x2,y2). This would be an exception based system, where all objects would be included unless specifically excluded. Exclusion could be done on a per object, per object-type, or per family basis. Certain object types would be excluded by default (Tilemaps). There would be an option to store/retrieve this data as JSON (the Load/Save options). For example, we could easily divide a layout into chunks and store them in a dictionary. Then, using the complimentary 'Load from JSON' command, we can spawn chunks back out at will. This is essentially a sort of 'save/load state' command that can function on a user specified area. Reset would work as described. Conflicts (the ball scenario) would default to option 1: Destroy both balls, create a new one. There would be an setting (Object Persistence?) under layout settings to change this to option number 4: Create a new object, leave the old ones. Void would simply destroy all the non-excluded objects within the specified area. Objects moved into the area would also be destroyed (unless excluded). Objects moved outside that area would not be destroyed. For Void/Reset: To handle the lag of creating/destroying all those objects at once, there could be an option to 'lazy load', where only 'X' number of objects would be spawned/destroyed per tick. This would default to 0 (create/destroy all at once). While lazy loading, all objects would be 'inactive' (invisible, no collisions, behaviors inactive) until all objects for the given area were created. Perhaps inactive objects shouldn't even be available to be picked in events (otherwise, event based logic might get messed up).

      b. Size of runtime/data.js file:
      Is there any way this data can be compressed in transit to the user? I notice that dropping my 'Ginormous' 6mb file into 7zip spits out an archive of merely 400kb, a reduction of >magnitude. I have no idea if this is a practical suggestion, but it would be far more effective than truncating object positions, which could be done on our end if need be.

      c. Draw call performance:
      Could the existing collision cells opt be commandeered to set objects more than X cells away from the edges of the window invisible? Since the player is unlikely to be moving across vast expanses in a mere handful of ticks, couldn't this be handled pretty efficiently?

      d. Loading the Layout:
      There is still the initial load of the layout, which, with all the objects present, would be very slow...even if you just proceeded to delete most of them, excepting those near the player. One approach is to use the layout zone commands to process the final layout, store the 'chunks' in a dictionary, export said dictionary file to a master JSON, and include said JSON file (WorldDict) with the game. Then, just spawn into a blank layout with identical properties to the master layout, and spawn those chunks out as needed. There is still a measure of tedium to this approach, but the layout zone commands would streamline the process immensely.

    /tl;dr

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • Ashley

    That's a very valid point. Playing an open streaming world over the web would result in Second Life effect. Where areas are white shaded blocks until textures load. There is very clear white out until then. From a solid game play perspective this is not acceptable. So playing open streaming worlds online is no good unless of course world building is that experience. So I still wouldn't consider closing the door on asset management.

    On the flip side is that the open streaming worlds should only be designed local games. Ie nodewebkit or packed games for mobile. That way the assets are already all there to access and don'y need to be uploaded. Then there is much less load time.

    As for unloading and loading of assets. Well cell like structure with let's say screen size + 50% dimension as a sample. The system would keep the screen and 1 cell size around the screen as loaded. When the player transitions a cell the farthest set then starts to unload.

    As for teleporation white screen. If Teleportation is needed then use small subset of thematic graphics to each area that works as a world global set of assets. However since they only constitute 10% of each area.

    So what I guess I'm saying is that letting players developers have access is important. If it's online world builder games were missing assets are ok and expected and if that's not acceptable such as GTA then the developer and designers can tinker ways around it by using controlled methods. however that capability needs to exist first.

    However even GTA and Midnight Club suffer pop in effects. I'll use Midnight Club more. Midnight Club is an open world racing game. I'm pretty sure uses the same base engine as GTA3 back then. Players are given race tracks that consist of markers. however the players are free to get the markers any way they want. Early in the game popup isn't a problem. But I have to admit later in the game on the faster cars and bikes popups do occur. But seems to be handled by distance grid buffering. So even top end games still get hit by missing assets.

    I'm not asking for an open world engine. Just a way to flag objects that use images that if there object count is 0, then unload the entire image set. By default this shouldn't happen. I think web focus should have priority. As for asset loading.

    If game designers set goals such as no more than 2 thematic areas at one time. Then world design can take that into account and avoid issues. Developers are crazy nuts that can figure out possible solutions. Providing there isn't anything blocking them. However memory overload is a blocker.

    And as you say since WebGL can't do asynchronous loading, and at this time looks like WebGL can't do webworker ascyn loading. Then there is a blocker in the WebGl. So not much can be done at the moment. Pity. But maybe in 6 months.

  • So I'm thinking the best solution so far is simply an action to recreate the initial instances in a rectangle of the layout for a single object type. It would not destroy anything, since you can easily use a Destroy action to destroy everything yourself if that's what you want to happen, so you can have it both ways (either destroy and create, or keep everything and create).

    Since it only works for one type, then you could simply call a function which has a list of destroy/recreate actions for every object type you want to opt in to this resetting. Then you can use that function to reset arbitrary rectangles of the layout to its initial state for a specified list of objects. This doesn't involve saving and restoring any state, which I think is for the best anyway - that adds a lot of overhead (especially if they are static background objects or similar), and it can be done with events in cases that you want it as well. Or you can leave them still existing there and destroy the things around it, or we could still look in to ways to make leaving everything still perform well.

    I reviewed the engine code and creating objects should actually be pretty fast, but destroying large numbers of objects at once was slow. I've done some optimisation work for the next beta to make that a lot faster (I got one stress test running several times faster). So that should help make the destroy-sections approach work better.

    Is there any way this data can be compressed in transit to the user?

    I think most servers on the web have default settings that automatically apply compression to all text-based formats. So this should happen automatically with most servers.

    Could the existing collision cells opt be commandeered to set objects more than X cells away from the edges of the window invisible?

    Maybe - I wanted to when it was first implemented, but it's difficult enough that I couldn't figure out a good way to do it. The main complication is Z order. Collision cells don't care about ordering instances - they are simply either in it or not. Objects can belong to multiple collision cells at once, and multiple collision cells can be on-screen. So then how do obtain just the on-screen objects and then render them in their correct Z order? It's difficult to see how this wouldn't involve something like "gather everything on-screen then sort by Z order", but running a sort on all on-screen instances every tick could cause very poor performance for games with a small layout and a very large number of on-screen objects (e.g. bullet hell). There are possible solutions which don't require continual sorting, but they are pretty complicated. I'll think about it some more, it would be nice if it could be solved...

  • Sounds good to me

    I think saving object states should be done with events as you said, so we can store them in arrays/webstorage for later on. Anything built in would only be for that session which isn't very useful imo.

  • > Could the existing collision cells opt be commandeered to set objects more than X cells away from the edges of the window invisible?

    >

    Maybe - I wanted to when it was first implemented, but it's difficult enough that I couldn't figure out a good way to do it. The main complication is Z order. Collision cells don't care about ordering instances - they are simply either in it or not. Objects can belong to multiple collision cells at once, and multiple collision cells can be on-screen. So then how do obtain just the on-screen objects and then render them in their correct Z order? It's difficult to see how this wouldn't involve something like "gather everything on-screen then sort by Z order", but running a sort on all on-screen instances every tick could cause very poor performance for games with a small layout and a very large number of on-screen objects (e.g. bullet hell). There are possible solutions which don't require continual sorting, but they are pretty complicated. I'll think about it some more, it would be nice if it could be solved...

    I'm afraid I don't understand. For draw calls, you are already looping thru all the objects on visible layers every tick, right? How would that be handled any differently? Why does Z order affect this? I'm probably missing something here...

    BTW, if I understand what I'm seeing in the c2runtime.js, the collision cells are set to the original width/height of the game window, is that correct? Just curious.

  • R0J0hound

    I downloaded your chunk_load_unload2.capx but when I put the events into my own game, only one of the two sprites would spawn, the rest just get deleted. Any fix for this? I set it up exactly like in the original chunk_load_unload2.capx but it doesn't seem to work?

  • To draw the screen correctly, you have to draw every object on-screen in order of their Z order (since it's a back-to-front renderer). Collision cells just store an unsorted list of objects. That doesn't matter for collisions: the order you check for collisions is totally unimportant, whereas ordering is crucial for correct rendering.

    Even if collision cells stored objects in their Z order, you could have 4 or more collision cells in the viewport at once. Since objects can cross multiple collision cells, you need to take all of these cells and merge them in to a single Z order list for correct rendering. It's hard to see how that doesn't come down to "collect all instances from on-screen cells, and then sort them". If lots of things are on-screen, the sort is a new extra step that wasn't needed before, and will have a performance impact. So it could just make it slower.

  • Nesteris I'm assuming you have multiple objects in single family, but your 'create object' event uses the family, not the individual objects. If that's the case then, well, this is the tediousness R0j0hound was talking about lol. You have to create them individually. If that's not the case then you'll have to post a .capx or something...or just wait until the next beta when the 'reload layout zone' or w/e it's called is added, which will more or less make that this existing method obsolete.

  • [quote:bpi7zt08]or just wait until the next beta when the 'reload layout zone' or w/e it's called is added, which will more or less make that this existing method obsolete.

    Wait, it's coming out? Are you sure? Oh wow. That's super!

    As for my .capx, could this be a suffice as a replacement?

    [attachment=0:bpi7zt08][/attachment:bpi7zt08]

    On start of the layout, the "spire"s in the chunk the player is in are present, but the ones out side the chunk are not. Are expected.

    However when I kill off the spires in the chunk I'm in and move to another chunk, the ones supposed to be there aren't.

    Then when I go back to the first chunk, the spires I killed don't respawn. But the Missile Ammo pick up does, regardless of how many times I pick it up and go out of and then return to the chunk. The best I got it working was having all the spires spawn regardless of which chunk they're in, but that's completely unhelpful.

    Also Tokinsom can you occasionally help me learn how to better use Construct 2 events? Not everything, just the really complicated things. You have my email right?

  • Nesteris Sounds like it. We narrowed it down to one action (Reload layout zone (x1,y1,x2,y2)) so yeah, we'll see. As for your problem with that .capx...Nothing is really standing out at the moment. Will have to look at it more.

    Ashley So it looks like, with this new action, it'll work like this:

    -Load entire layout as usual

    -Destroy objects outside of first zone with events

    -Reload layout zones and destroy outside objects as needed

    My only concern is that the whole layout is still created at the very start. Would this cause the game to hang for a bit? Even if you dedicate each layout to a single area, they could still be fairly large.

  • Tokinsom

    That's what I thought as well, lately all the events I've been pulling from other .capxs I have and putting them into others don't work. No idea why, I've been quadruple checking that I did everything right and it doesn't work. Really strange...

    Can I send you my .capx via email or something so you can take a look at it?

  • Nesteris

    The events look the same and it appears you have the family set up the same. The only other difference is that the "room" sprite and the "roomObjs" array are in a container with each other, which could have been overlooked.

  • I'm supposing that this idea was pretty much discontinued? It sounds like a great idea, especially when adding Multiplayer into the mix. I added a reply in this thread () and after looking around a bit more, found this one!

  • DatapawWolf

    It actually got solved, Ashley added in two new features to the engine.

    "System action: 'recreate initial objects'. Recreate the initially placed objects in the layout for a specific object type or family within a rectangular area. (Note this does not destroy anything, it only creates new instances.)"

    "System action: 'Reset persisted objects'. Revert all objects with the Persist behavior in their project to their initial state."

    Added in r191 and r192 beta releases. They're located in system actions.

    Edit: We also made Ashley test the engine further and he made performance improvements to the engine to make destroying objects significantly less taxing on the system.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)