Tilemaps, Datablocks, and Possible Frustrum?
by Jesse Allen · in Torque 2D Beginner · 11/09/2013 (12:35 am) · 51 replies
First and foremost, greetings to all here at the GG board. My name is Jesse and I have recently decided to begin learning to use T2D MIT. I've managed to follow all the basic tutorials about T2D I could find fairly smoothly. With help from previous posts on this board I have managed to get the console working in my new module outside of the T2D directory(big thanks for that!). I am proficient with some basic web languages like html, css, and php. Also I learned some basic lower level programming language concepts with Java a few years back, but even so I would probably just call myself a 'beginner' with game programming. With background and introductions out of the way, let's see if perhaps someone may be able to assist me with my way of thinking about tackling my most recent project.
After familiarizing myself with how T2D works, it seems that it is a perfect solution to help me bridge the gap to using lower level programming languages. I am fairly proficient at understanding the TorqueScript so far, although the project I am trying to make is confusing me as to where to begin. What I am wanting to accomplish, ultimately, is to have a side scrolling 2D game with ground tiles similar to Terraria. This would require (to the best of my understanding at this point):
1 - A tilemap of some kind that will allow each seperate tile to have its own attributes (i.e. collision).
2 - The tiles have to be able to be removed or replaced independently of any other nearby tiles if the player's 'character' is in range.
3 - The tilemap should be able to accept parameters so that you can tell the tilemap to render these tiles only on perhaps the bottom 30% of the screen or so. This would allow the tiles to be the 'ground' (basically the entire tilemap could be collidable until a block was knocked out) with a background layer floating behind to cover the top of the screen.
4 - The tiles would also need to be randomly generated (i.e. dirt, stone, iron). I could see perhaps the getRandom function being applied on a per tile basis?
5 - I had an idea that perhaps to save on performance some sort of frustrum system could be in place. As the scene moved to the left, for example, tiles would be placed ahead and removed behind. Say a column disappeared when it went out of the camera's view, and was preloaded when it was about to come into view.
I feel like this is completely possible somehow, although I just can't quite figure it out. Here are some of the things I've considered during my research into this problem:
I thought about using the T2D Game Builder and making use of its Image Maps/Datablocks system there. So I downloaded the trial version and was able to see right away much of what I'm describing here the TGB can do...BUT it occurred to me that perhaps all of that functionality was still in T2D just by use of TorqueScript. This brings me to my first question:
docs.garagegames.com/tgb/official/content/documentation/Reference/Image%20Maps.h...
If I were to become very familiar with the usage of Image Maps detailed here for TGB, could that same TorqueScript code be used in the more current T2D MIT? I ask this because I would prefer to move forward with my understanding of the newer engine if this TGB functionality would still work by use of the TorqueScript. There would be no GUI for it, but if the script would still work I'd be happy learning more.
Moving on, I had also found this resource that William Hilke developed for T2D MIT here:
www.garagegames.com/community/blogs/view/22199
I feel like I'm getting closer, although this resource brings to light a couple other questions: Would this TMX map solution ultimately allow me to do this with T2D(given much hair-pulling surely)? Also is this even necessary or are there other gui type solutions that would allow me to input all the information on a per tile basis and then use the resulting tilemap with T2D?
Taking this entire idea another step forward, on to the frustrum thing. Being new to game programming and engine rendering I am not sure if the engine takes care of what is out of view of the camera or I would need to create a solution. For example: Say we have a level and on a single row horizontally it spans 10,000 tiles. I wouldn't want to create all those tiles (that's just one row!) on level load, only the tiles that are on the screen or maybe really close around the outside of the camera. The player's 'character' sprite would be fixed at the center of the screen and as the player moved left/right the frustrum system could perhaps fill in and take away dynamically. This could even possibly allow for really huge horizontal spans across the level. I noticed while trying out the TGB, there were values that could be input for the scrolling although I am uncertain as to whether or not this 'culls' tiles out of view. Any clarification would be greatly appreciated here!
Here is an article I found about very basic 2D flash game concepts:
www.wildbunny.co.uk/blog/2011/12/11/how-to-make-a-2d-platform-game-part-1/
It is a good little read, if only for the 'mental' type of concepts introduced that should carry over to T2D if applied with TorqueScript correctly. Specifically on the first page (Part 1), he describes a 'Wallace and Gromit' style of placing tiles that looks like exactly what I'm after. Is there a way to approach this with TorqueScript?
As a prime example of where I'm going, check out this game Darkout that was made with T2D. To the best of my knowledge, it would appear that TGB was used partially to get the tiles working. Although I am fairly sure there are other (perhaps C++) scripts helping this along. This game Darkout is in beta currently, but this is spot on very close to my goals:
www.youtube.com/watch?v=4PDrLm94QLE (Gameplay video of Darkout - word of warning: the Gamezine theme music is loud and abrasive at the start of the video turn it down a bit)
If you've come this far, thank you for taking an interest and I look forward to hearing from you if you may be able to help. This is sort of a roadblock for me at this point because the simple placement of tiles needs to be so dynamic. Also I feel like this will likely be one of the most difficult (probably more simple than I think once a solution presents itself) things to implement. I can fiddle around with the sprites, assets, and other objects once I have a good dynamic tilemap system that will run on some sort of frustrum! Even if it takes a great deal of research to ultimately get this to work, any sort of direction at this point could be helpful. Cheers!
After familiarizing myself with how T2D works, it seems that it is a perfect solution to help me bridge the gap to using lower level programming languages. I am fairly proficient at understanding the TorqueScript so far, although the project I am trying to make is confusing me as to where to begin. What I am wanting to accomplish, ultimately, is to have a side scrolling 2D game with ground tiles similar to Terraria. This would require (to the best of my understanding at this point):
1 - A tilemap of some kind that will allow each seperate tile to have its own attributes (i.e. collision).
2 - The tiles have to be able to be removed or replaced independently of any other nearby tiles if the player's 'character' is in range.
3 - The tilemap should be able to accept parameters so that you can tell the tilemap to render these tiles only on perhaps the bottom 30% of the screen or so. This would allow the tiles to be the 'ground' (basically the entire tilemap could be collidable until a block was knocked out) with a background layer floating behind to cover the top of the screen.
4 - The tiles would also need to be randomly generated (i.e. dirt, stone, iron). I could see perhaps the getRandom function being applied on a per tile basis?
5 - I had an idea that perhaps to save on performance some sort of frustrum system could be in place. As the scene moved to the left, for example, tiles would be placed ahead and removed behind. Say a column disappeared when it went out of the camera's view, and was preloaded when it was about to come into view.
I feel like this is completely possible somehow, although I just can't quite figure it out. Here are some of the things I've considered during my research into this problem:
I thought about using the T2D Game Builder and making use of its Image Maps/Datablocks system there. So I downloaded the trial version and was able to see right away much of what I'm describing here the TGB can do...BUT it occurred to me that perhaps all of that functionality was still in T2D just by use of TorqueScript. This brings me to my first question:
docs.garagegames.com/tgb/official/content/documentation/Reference/Image%20Maps.h...
If I were to become very familiar with the usage of Image Maps detailed here for TGB, could that same TorqueScript code be used in the more current T2D MIT? I ask this because I would prefer to move forward with my understanding of the newer engine if this TGB functionality would still work by use of the TorqueScript. There would be no GUI for it, but if the script would still work I'd be happy learning more.
Moving on, I had also found this resource that William Hilke developed for T2D MIT here:
www.garagegames.com/community/blogs/view/22199
I feel like I'm getting closer, although this resource brings to light a couple other questions: Would this TMX map solution ultimately allow me to do this with T2D(given much hair-pulling surely)? Also is this even necessary or are there other gui type solutions that would allow me to input all the information on a per tile basis and then use the resulting tilemap with T2D?
Taking this entire idea another step forward, on to the frustrum thing. Being new to game programming and engine rendering I am not sure if the engine takes care of what is out of view of the camera or I would need to create a solution. For example: Say we have a level and on a single row horizontally it spans 10,000 tiles. I wouldn't want to create all those tiles (that's just one row!) on level load, only the tiles that are on the screen or maybe really close around the outside of the camera. The player's 'character' sprite would be fixed at the center of the screen and as the player moved left/right the frustrum system could perhaps fill in and take away dynamically. This could even possibly allow for really huge horizontal spans across the level. I noticed while trying out the TGB, there were values that could be input for the scrolling although I am uncertain as to whether or not this 'culls' tiles out of view. Any clarification would be greatly appreciated here!
Here is an article I found about very basic 2D flash game concepts:
www.wildbunny.co.uk/blog/2011/12/11/how-to-make-a-2d-platform-game-part-1/
It is a good little read, if only for the 'mental' type of concepts introduced that should carry over to T2D if applied with TorqueScript correctly. Specifically on the first page (Part 1), he describes a 'Wallace and Gromit' style of placing tiles that looks like exactly what I'm after. Is there a way to approach this with TorqueScript?
As a prime example of where I'm going, check out this game Darkout that was made with T2D. To the best of my knowledge, it would appear that TGB was used partially to get the tiles working. Although I am fairly sure there are other (perhaps C++) scripts helping this along. This game Darkout is in beta currently, but this is spot on very close to my goals:
www.youtube.com/watch?v=4PDrLm94QLE (Gameplay video of Darkout - word of warning: the Gamezine theme music is loud and abrasive at the start of the video turn it down a bit)
If you've come this far, thank you for taking an interest and I look forward to hearing from you if you may be able to help. This is sort of a roadblock for me at this point because the simple placement of tiles needs to be so dynamic. Also I feel like this will likely be one of the most difficult (probably more simple than I think once a solution presents itself) things to implement. I can fiddle around with the sprites, assets, and other objects once I have a good dynamic tilemap system that will run on some sort of frustrum! Even if it takes a great deal of research to ultimately get this to work, any sort of direction at this point could be helpful. Cheers!
About the author
Skilled Artist and Musician. Intermediate Torque Developer.
#2
github.com/GarageGames/Torque2D/wiki/CompositeSprite-Guide
CompositeSprites have render culling built in so I don't know if a frustum is really needed. It's also worth looking through the CompositeSpriteToy scripts for practical examples on how to use it.
Oh, and welcome to the T2D community. Hope we can help you figure out how to implement your game ideas.
11/09/2013 (2:29 am)
You brought up a lot of topics in your post, time is a bit short on my end to address everything in one post though. For starters - tilemaps are handled in T2D MIT with the CompositeSprite class. Here is a short guide on its functionality:github.com/GarageGames/Torque2D/wiki/CompositeSprite-Guide
CompositeSprites have render culling built in so I don't know if a frustum is really needed. It's also worth looking through the CompositeSpriteToy scripts for practical examples on how to use it.
Oh, and welcome to the T2D community. Hope we can help you figure out how to implement your game ideas.
#3
Networking
Simple answer here. Torque 2D does not have real-time networking. If your goal is to have multiplayer like Terraria, this would require a decent amount of time and C++ coding. It's not as simple as just updating position over the network. First, you'll have to do all the basic client/server connection stuff. Next, delivery of data to both ends. Then, you have to deal with providing information based on the location of each player. If they are both at separate ends of a map, you do not want to render, handle logic, and calculate physics for all the "empty space" in the middle. Empty space being stuff neither place can see. T2D's rendering already handles that automatically.
Finally, the hardest part, is handling physics. Box2D is not setup for networking. It's a single world simulation. It takes input in the way of bodies, forces, and joints. It outputs the the updated position, velocity, and collision responses. For the sake of networking, you will have to hotwire the physics or use a custom solution. The server would be the Box2D authority. It runs the simulation. Clients would not run their own Box2D. They would just update based on what the server is telling them.
Getting functional, real-time networking is no trivial matter.
11/09/2013 (9:24 am)
Welcome! Man, this thread could seriously take up my whole weekend. I have to break this up into separate posts.Quote:is to have a side scrolling 2D game with ground tiles similar to TerrariaThis is why it's going to suck me in. First, I LOVE TERRARIA. Second, due to my love of the game and T2D, I've often though about how to create something similar using the engine. I've always reached the same conclusion on most difficult technical hurdles: networking and the terrain system.
Networking
Simple answer here. Torque 2D does not have real-time networking. If your goal is to have multiplayer like Terraria, this would require a decent amount of time and C++ coding. It's not as simple as just updating position over the network. First, you'll have to do all the basic client/server connection stuff. Next, delivery of data to both ends. Then, you have to deal with providing information based on the location of each player. If they are both at separate ends of a map, you do not want to render, handle logic, and calculate physics for all the "empty space" in the middle. Empty space being stuff neither place can see. T2D's rendering already handles that automatically.
Finally, the hardest part, is handling physics. Box2D is not setup for networking. It's a single world simulation. It takes input in the way of bodies, forces, and joints. It outputs the the updated position, velocity, and collision responses. For the sake of networking, you will have to hotwire the physics or use a custom solution. The server would be the Box2D authority. It runs the simulation. Clients would not run their own Box2D. They would just update based on what the server is telling them.
Getting functional, real-time networking is no trivial matter.
#4
This can be broken down into several pieces. First, you need a basic data structure that defines a tile. Then you need the world generation that places tiles. Terraria is completely procedural, with some rules to dictate what tiles show up at which depths. It also handles digging caves, adding moss, water placement, and so on. They do not use any kind of editors like Tiled (TMX format).
I've thought quite a bit about the trickiest part to this. Once again, it comes down to physics. Box2D is powerful, optimized, and gets the job done for most games. However, think about the sheer number of blocks in a single Terraria world. Heck, think about how many are on screen just in the player's zone? There are several approaches to handling this with stock T2D, though I'm not exactly sure if I've isolated the best way.
First, completely forget the idea of creating a Box2D body with a square collision for every single tile. The game will collapse on itself and die a horrible death. Perhaps the best way is to dynamically create and destroy collision shapes as the player encounters a "zone". For the sake of simplicity, let's say a world consists of 150 tiles wide, 2 tiles down. At any given time, the player will be able to see 2 tiles down, 50 tiles across. That gives you a few zones to work with. Let's put them in the middle of the map to start.
Zone1===Player===Zone3
[50 tiles] [50 tiles] [50 tiles]
[50 tiles] [50 tiles] [50 tiles]
The player is in zone 2, with zone 1 and 3 out of view. You do not want to perform any rendering, physics, or logic in zones 1 and 2. As the player moves into one zone, disable everything on the last one. So far so good. Now what about collision? Well, to keep it simple let's say each tile is a perfect square. You could create a collision shape with four points. You could get really fancy and create edge collision shapes for any areas that do not contain a tile.
What's going to cause hitching is when you are dynamically creating and destroying bodies/collision shapes. In my above example, each time the player moves into a zone the system will destroy 100 shapes and create 100 shapes. On a decent rig, that may not be terrible. Imagine if we go up to 1,000 on screen at once. That's gonna get bad. Not to mention that a client may not be handling this. The server would likely be feeding all this info to the player, so now you have to compensate for net lag.
If you've played Terraria on Xbox, especially early on, you might have noticed the poor network updating while in a multiplayer game. My friend would host a game, I would join. If I was moving to fast, like falling down a hellevator, the networking could not update fast enough and I would fall basically into a black hole infinitely. The system couldn't give me rendering or collision fast enough. Danger, danger, danger.
11/09/2013 (9:30 am)
World GenerationThis can be broken down into several pieces. First, you need a basic data structure that defines a tile. Then you need the world generation that places tiles. Terraria is completely procedural, with some rules to dictate what tiles show up at which depths. It also handles digging caves, adding moss, water placement, and so on. They do not use any kind of editors like Tiled (TMX format).
I've thought quite a bit about the trickiest part to this. Once again, it comes down to physics. Box2D is powerful, optimized, and gets the job done for most games. However, think about the sheer number of blocks in a single Terraria world. Heck, think about how many are on screen just in the player's zone? There are several approaches to handling this with stock T2D, though I'm not exactly sure if I've isolated the best way.
First, completely forget the idea of creating a Box2D body with a square collision for every single tile. The game will collapse on itself and die a horrible death. Perhaps the best way is to dynamically create and destroy collision shapes as the player encounters a "zone". For the sake of simplicity, let's say a world consists of 150 tiles wide, 2 tiles down. At any given time, the player will be able to see 2 tiles down, 50 tiles across. That gives you a few zones to work with. Let's put them in the middle of the map to start.
Zone1===Player===Zone3
[50 tiles] [50 tiles] [50 tiles]
[50 tiles] [50 tiles] [50 tiles]
The player is in zone 2, with zone 1 and 3 out of view. You do not want to perform any rendering, physics, or logic in zones 1 and 2. As the player moves into one zone, disable everything on the last one. So far so good. Now what about collision? Well, to keep it simple let's say each tile is a perfect square. You could create a collision shape with four points. You could get really fancy and create edge collision shapes for any areas that do not contain a tile.
What's going to cause hitching is when you are dynamically creating and destroying bodies/collision shapes. In my above example, each time the player moves into a zone the system will destroy 100 shapes and create 100 shapes. On a decent rig, that may not be terrible. Imagine if we go up to 1,000 on screen at once. That's gonna get bad. Not to mention that a client may not be handling this. The server would likely be feeding all this info to the player, so now you have to compensate for net lag.
If you've played Terraria on Xbox, especially early on, you might have noticed the poor network updating while in a multiplayer game. My friend would host a game, I would join. If I was moving to fast, like falling down a hellevator, the networking could not update fast enough and I would fall basically into a black hole infinitely. The system couldn't give me rendering or collision fast enough. Danger, danger, danger.
#5
Imagine your character is standing on 7 horizontal tiles. The character is on the center tile so that there are 3 tiles to his left and 3 tiles to his right. As soon as the character steps onto the next tile to the right, the tile that was originally all the way to the left (the first tile) disappears. Simultaneously a new tile is placed all the way to the right. This way the character is always standing on 7 tiles at the center tile. Logically, I'm thinking to myself roughly 'if the character steps on this tile, render this and cull that'.
@Mike: Thank you very much for the referral to the CompositeSprites class. I believe this could be exactly what I am needing to learn more about in order to progress with the idea. I know that I'm new to the engine and will have to apply myself, knuckle down and learn in order to achieve any of this. I just want to be sure that all of my learning and progression is in the right direction to start with. This is why I am definately in favor of trying to achieve my goals with T2D MIT via TorqueScript over relying on dated gui tools. This really helps me, Mike, it is a big step in the right direction!
edited to add: Mich just responded while I was posting this so I will review all of this. Man what an amazing community, so helpful and on point to get the job done! Good form!
11/09/2013 (9:34 am)
@Stefan: Your solution sounds very relevant, thank you for sharing. I would be interested in learning more about the actual code involved with creating and fetching the grid containers (i.e. functions, loops). I believe I first learned of frustrum methods when Chris Taylor used it with the original Dungeon Siege game. It was 3D, but basically it would only render and call on the tiles, models, etc. that were on-screen. His implementation was interesting, it seemed almost as if the actual rendering of new tiles and removal of old ones were linked to previous tiles traversed over by the player's character. I'll try my best to explain:Imagine your character is standing on 7 horizontal tiles. The character is on the center tile so that there are 3 tiles to his left and 3 tiles to his right. As soon as the character steps onto the next tile to the right, the tile that was originally all the way to the left (the first tile) disappears. Simultaneously a new tile is placed all the way to the right. This way the character is always standing on 7 tiles at the center tile. Logically, I'm thinking to myself roughly 'if the character steps on this tile, render this and cull that'.
@Mike: Thank you very much for the referral to the CompositeSprites class. I believe this could be exactly what I am needing to learn more about in order to progress with the idea. I know that I'm new to the engine and will have to apply myself, knuckle down and learn in order to achieve any of this. I just want to be sure that all of my learning and progression is in the right direction to start with. This is why I am definately in favor of trying to achieve my goals with T2D MIT via TorqueScript over relying on dated gui tools. This really helps me, Mike, it is a big step in the right direction!
edited to add: Mich just responded while I was posting this so I will review all of this. Man what an amazing community, so helpful and on point to get the job done! Good form!
#6
With that in mind, forget about datablocks. t2dImageMapDatablock and t2dAnimationDatablock are old and TGB specific. Same goes for t2dStaticSprite and t2dAnimatedSprite. For T2D, an entirely new system for asset and sprite management was introduced. Now, there is only a Sprite. It can be animated or non-animated. You can create an ImageAsset or AnimationAsset. They are similar to the old datablocks, but with a ton of garbage removed. The asset system in general is faster and better optimized than what TGB offered.
11/09/2013 (9:52 am)
Now, I highly recommend that you read through the wiki links Mike posted. Now that I've used both TGB and T2D, I would most definitely use T2D for a game similar to Terraria. It's just more powerful, even if it lacks editors. The rendering, physics, asset system, module system, and general improvements are worth it.With that in mind, forget about datablocks. t2dImageMapDatablock and t2dAnimationDatablock are old and TGB specific. Same goes for t2dStaticSprite and t2dAnimatedSprite. For T2D, an entirely new system for asset and sprite management was introduced. Now, there is only a Sprite. It can be animated or non-animated. You can create an ImageAsset or AnimationAsset. They are similar to the old datablocks, but with a ton of garbage removed. The asset system in general is faster and better optimized than what TGB offered.
#7
11/09/2013 (9:54 am)
Happy to provide some guidance Jesse. As you can tell, I've thought quite a lot about this. Again, Terraria is one of my favorite games. I'm still enjoying the latest update. Starbound is going to be released soon, which will be a whole new experience with a similar flavor.
#8
I noticed in reviewing the "zone" concept you explained above, it is very similar to the frustrum type method Chris Taylor was using. Although there would be a fundamental difference that I believe may be part of the solution. This could get lengthy; please bear with me. First, your example was as follows:
Zone1===Player===Zone3
[50 tiles] [50 tiles] [50 tiles]
[50 tiles] [50 tiles] [50 tiles]
What you are doing here is handling all of the tiles that are visible horizontally (and vertically going down to the bottom of the screen from the top of your surface) as a "zone". Let's look at this with a little bit higher resolution (visually) to gain a little more insight. Here's an example of the same concept you introduced:
Zone 1=======Player========Zone 2
xxxxxxxxxx|xxxxxxxxxx|xxxxxxxxxx|
xxxxxxxxxx|xxxxxxxxxx|xxxxxxxxxx|
Each 'x' is a tile of course. In each zone there are 20 tiles, 10 in each row. With the idea you presented, as a player moved 40 tiles would be destroyed and created simultaneously by adding and removing zones.
What I would propose is not to destroy and create by a zone horizontally but rather vertically and on a single column basis. The player would be in the center and if he took a single step to the next tile horizontally we would destroy the column of tiles that just went off screen and create a column of tiles ahead (the direction the character is facing). This would look sort of like this:
(edit: Alright, picture is finished. Hope this makes more sense!)
s1213.photobucket.com/user/rockoutsolid/media/Concept/frustrum_concept2.png.html
What's going on here is if the player steps on a tile, the tile itself that he stepped on triggers the action to destroy and create a column at the far edge of the screen. An example could be:
if the player steps on %stepR, destroy Column L and create Column R.
In this example the player is moving right. This would mean only 4 tiles had to be created and destroyed simultaneously instead of the "zones" which would be 40 tiles at a time. Basically the rendering would take place on a per-tile basis so that each individual tile would just create/destroy vertically what's coming. The same could be applied vertically I would imagine, in that as you would 'dig' down one tile a row at the bottom would appear while a row at the top would disappear.
I hope this makes sense, and more importantly I hope that this is possible to do with the use of (perhaps) CompositeSprites. Any further insight would be helpful, and if nothing else thank you all for your help thus far it is all very enlightening to say the least.
11/09/2013 (10:30 am)
@Mich: Firstly, thanks a lot for your in depth look explanation about this. I am very new with T2D, so my knowledge of implementing any of this even for testing is very limited. This being said, networking would be the very last of my concerns as I am not even sure where to begin with rendering the tiles just yet. If I could actually render the "zones" and have the other zones pop in and out as the player moved I'd be fairly impressed. I noticed in reviewing the "zone" concept you explained above, it is very similar to the frustrum type method Chris Taylor was using. Although there would be a fundamental difference that I believe may be part of the solution. This could get lengthy; please bear with me. First, your example was as follows:
Zone1===Player===Zone3
[50 tiles] [50 tiles] [50 tiles]
[50 tiles] [50 tiles] [50 tiles]
What you are doing here is handling all of the tiles that are visible horizontally (and vertically going down to the bottom of the screen from the top of your surface) as a "zone". Let's look at this with a little bit higher resolution (visually) to gain a little more insight. Here's an example of the same concept you introduced:
Zone 1=======Player========Zone 2
xxxxxxxxxx|xxxxxxxxxx|xxxxxxxxxx|
xxxxxxxxxx|xxxxxxxxxx|xxxxxxxxxx|
Each 'x' is a tile of course. In each zone there are 20 tiles, 10 in each row. With the idea you presented, as a player moved 40 tiles would be destroyed and created simultaneously by adding and removing zones.
What I would propose is not to destroy and create by a zone horizontally but rather vertically and on a single column basis. The player would be in the center and if he took a single step to the next tile horizontally we would destroy the column of tiles that just went off screen and create a column of tiles ahead (the direction the character is facing). This would look sort of like this:
(edit: Alright, picture is finished. Hope this makes more sense!)
s1213.photobucket.com/user/rockoutsolid/media/Concept/frustrum_concept2.png.html
What's going on here is if the player steps on a tile, the tile itself that he stepped on triggers the action to destroy and create a column at the far edge of the screen. An example could be:
if the player steps on %stepR, destroy Column L and create Column R.
In this example the player is moving right. This would mean only 4 tiles had to be created and destroyed simultaneously instead of the "zones" which would be 40 tiles at a time. Basically the rendering would take place on a per-tile basis so that each individual tile would just create/destroy vertically what's coming. The same could be applied vertically I would imagine, in that as you would 'dig' down one tile a row at the bottom would appear while a row at the top would disappear.
I hope this makes sense, and more importantly I hope that this is possible to do with the use of (perhaps) CompositeSprites. Any further insight would be helpful, and if nothing else thank you all for your help thus far it is all very enlightening to say the least.
#9
I wanted to add here that if you take a look at that game Darkout I linked above, you can see that they did manage to make this work using T2D and the TGB. I know that this was done using TGB and the datablock functionality at least for something. Upon perusing the file folders of the game I found a .T2d file within a folder named 'level' that is an identical match to the .T2d file generated with the TGB Image Map tool. This is also working very smoothly with graphics quality as good as I would ever need for such a project. This game has multiplayer coming in December as well.
Really good job here, and this game in particular is my inspiration for the new project. This project proves that it is definately possible using even the outdated tools and engine. The question is: How'd they do it?
11/09/2013 (11:39 am)
@Mich: Yeah man I am excited to play Starbound! It's going to be a really cool game!I wanted to add here that if you take a look at that game Darkout I linked above, you can see that they did manage to make this work using T2D and the TGB. I know that this was done using TGB and the datablock functionality at least for something. Upon perusing the file folders of the game I found a .T2d file within a folder named 'level' that is an identical match to the .T2d file generated with the TGB Image Map tool. This is also working very smoothly with graphics quality as good as I would ever need for such a project. This game has multiplayer coming in December as well.
Really good job here, and this game in particular is my inspiration for the new project. This project proves that it is definately possible using even the outdated tools and engine. The question is: How'd they do it?
#10
Additionally I have created a new module named TileLogic to experiment with different ways of rendering this idea. The TileLogic module is just using a Scroller Object positioned near the bottom of the screen with RepeatX and Y values to fill in the bottom of the screen with tiles. It also contains some other scroller objects for immersion :)
I have all the gui working for the console/new Sandbox. I have the saving preferences working, saving to the DS_STORE file. This way I can start the program, it launches the default toy via preferences, and I can access console and toolbox to interact with modules.
I know that this all sounds a bit redundant. You may wonder, "Why not just work with the project in the T2D directory which already has sandbox/console functionality?" It is simply for learning purposes, and by starting with nothing I can look over the code within every single .cs file as I try to rebuild a new and functional sandbox. This has proven to be extremely enlightening.
Today I will be looking more into the tiling options and perhaps customize the gui. I am adapting to the program very well at this point, and will post more about my progress here.
P.S. I feel as though my explanation about the 'frustrum' above was not entirely clear. On hindsight, it almost appears as if the idea I am presenting and the 'zone' idea from Mich are one in the same. I will also update this to be more clear (when time allows), if for nothing more than my personal reference and planning of the project.
11/10/2013 (8:30 am)
I have been progressing very well with getting familiar with T2D. I integrated the Console and the Sandbox module into my project (renamed Sandbox and all the calls to it to understand what was going on under the hood). I also cloned the CompositeSpriteToy module and have been experimenting with different paramaters there. Additionally I have created a new module named TileLogic to experiment with different ways of rendering this idea. The TileLogic module is just using a Scroller Object positioned near the bottom of the screen with RepeatX and Y values to fill in the bottom of the screen with tiles. It also contains some other scroller objects for immersion :)
I have all the gui working for the console/new Sandbox. I have the saving preferences working, saving to the DS_STORE file. This way I can start the program, it launches the default toy via preferences, and I can access console and toolbox to interact with modules.
I know that this all sounds a bit redundant. You may wonder, "Why not just work with the project in the T2D directory which already has sandbox/console functionality?" It is simply for learning purposes, and by starting with nothing I can look over the code within every single .cs file as I try to rebuild a new and functional sandbox. This has proven to be extremely enlightening.
Today I will be looking more into the tiling options and perhaps customize the gui. I am adapting to the program very well at this point, and will post more about my progress here.
P.S. I feel as though my explanation about the 'frustrum' above was not entirely clear. On hindsight, it almost appears as if the idea I am presenting and the 'zone' idea from Mich are one in the same. I will also update this to be more clear (when time allows), if for nothing more than my personal reference and planning of the project.
#11
So I thought I would spent some time making an example of what I *THINK* Mr. Allen here is trying to say:
In hindsight, I dont know how fast this method will be, perhaps C++ would be more appropriate for this situation.
11/10/2013 (12:47 pm)
Well, all this talk of Frustrum had me quite confounded...So I thought I would spent some time making an example of what I *THINK* Mr. Allen here is trying to say:
// Just an example, a block template with no real defining features, assume it's 1 square meter in size, and its x and y dimensions are equal
new Sprite(Block)
{
class = Block;
};
//example code for adding in tiles, doesn't add a collsion shape, that's the hard part ;)
function addbrick(%posx, %posy, %type)
{
// making them whole numbers because for a grid, it's sensible enough to do so
%posx = mRound(%posx);
%posy = mRound(%posy);
// this will spawn an object inheriting the values of our previously defined object template
eval("%block = new Sprite(:" @ %type @ ");");
// actually make the co0rdinates mean something
%block.position = %posx, %posy;
//array to store all tiles in the map
$TileArray[%posx, %posy] = %block.class SPC %block; // could be anything stored in here, from a series of flags, to an ordered string containing information about the block's type, state, etc.
// add the brick to the scene
YOURSCENE.add(%block);
}
function directionCheck(%curpos, %lastpos)
{
//moving in the positive direction
if(%curpos > %lastpos)
return 1;
//Stan-ding-still! Stan-ding-still!
if(%curpos == %lastpos)
return 0;
//moving in the negative direction
if(%curpos < %lastpos)
return -1;
}
//this wont work for you completely, but it gets the point across I think.
function Player::Cleanup(%player)
{
// find out the player's approximate coordinates
%x = mRound(getword(%player.position, 0));
%y = mRound(getword(%player.position, 1));
//you need to determine where the player is going, so compare their current position to one we sampled previously, I'll say that in this case we store the position of the player at the last check to be stored in a dynamic feild called lastposition
%lx = getword(%player.lastposition, 0);
%ly = getword(%player.lastposition, 1);
%xd = directionCheck(%x, %lx);
%yd = directionCheck(%y, %ly);
// if they are standing still, we dont need to do all of this, so we can just stop right now.
if(%xd == 0 && %xy == 0)
return;
// assuming that the camera makes a 20x world unit square around the player, obviously you'd have to rework this, as this is a pretty small scene...
// x direction first
for(%i=0; %i<20; %i++)
{
//the x value we are going to use for added bricks
%fx = %x + 10(%xd); // 20/2 = 10, 10*(direction) allows us to go either way
// x for deleted's
%bx = %x - 10(%xd);//same logic as above, but going backwards
//whoa... Ok, this just finds the Handle of the bricks we are deleting and deletes them.
getword($TileArray[%bx,(%i+(%y-10))], getwordcount($TileArray[%bx,(%i+(%y-10))]) - 1).delete();
//add blocks
addbrick(%fx, (%i+(%y-10)), getword($TileArray[%fx,(%i+(%y-10))], 0));
}
//didnt really think this one through as well, but I'm getting tired, and the first one should get the point across just fine, I think.
for(%i=0; %i<20; %i++)
{
//the y value we are going to use for added bricks
%fy = %y + 10(%yd); // 20/2 = 10, 10*(direction) allows us to go either way
// y for deleted's
%by = %y - 10(%yd);//same logic as above, but going backwards
//whoa... Ok, this just finds the Handle of the bricks we are deleting and deletes them.
getword($TileArray[(%i+(%x-10)),%by], getwordcount($TileArray[(%i+(%x-10)),%by]) - 1).delete();
//add blocks
addbrick( (%i+(%x-10)) , %fy , getword($TileArray[(%i+(%x-10)),%fy],0) );
}
//Give the player a new last position for next run
%player.lastposition = %x SPC %y
//Thank god it's over...
}
//I'm assuming you'll want to have more than one player later, So I'd change this up a bit.
Player.startTimer("Cleanup",100);This is my attempt at making something I think SHOULD do what you want. Obviously this wont actually do the job you want out of the box, but maybe it'll save you some time with the general algorithm(if I didnt muck it up, that is).I commented almost every line, so even if this cod doesn't work, you know the logic it's supposed to be based on. In hindsight, I dont know how fast this method will be, perhaps C++ would be more appropriate for this situation.
#12
i1213.photobucket.com/albums/cc466/rockoutsolid/Concept/frustrum_rev2.png
In this example there are 2 horizontal rows of blocks. Each row contains 15 blocks. 30 blocks within the scene.
Now, if we were to consider all 30 blocks one "Zone" and have 3 Zones next to each other horizontally we would have 90 blocks total. In Mich's original example, it would look like so:
Zone1===Player===Zone3
[15 tiles] [15 tiles] [15 tiles]
[15 tiles] [15 tiles] [15 tiles]
Additionally, if we were to delete Zone1 and create Zone3 as the player moved right we would be constantly rendering 60 tiles at a time.
What this image is proposing: Instead of calling big groups of tiles (Zones) only call and delete the tiles just at the edge of the scene. This would only be rendering 4 tiles simoultaneously as opposed to 60. Hopefully that is more clear.
@Doctor Fail: Thank you very much for taking the time to look into this with me. I will copy this code and give it thorough study. I am very new to T2D and just getting my head around the TorqueScript; however, it's by picking apart the logic within scripts like these that I am learning. This is very much appreciated! After I am able to review this code, I'll give feedback.
Moving forward, I have been learning more about the Composite Sprites and really it seems as though this may just be the answer for me. Regardless of prior theories here, it is all obsolete if indeed the Composite Sprites can cull the blocks outside of the scene boundaries automatically. I believe this is indeed the case. I found this old blog by Melv May introducing Composite Sprites:
www.garagegames.com/community/blogs/view/22132
In Part 3 of this blog (which is linked here) Melv details his initial goals, which in all honesty appears to be much like what I am trying to achieve:
I will continue to explore different ways to implement these blocks, both by using Composite Sprites and by starting from scratch with some sort of "Frustrum" code. Any additional insight is always welcomed, of course. Cheers, I will update here on any progress.
11/11/2013 (8:10 am)
Alright, I finally found time to update my image to reiterate the theory. Take a look:i1213.photobucket.com/albums/cc466/rockoutsolid/Concept/frustrum_rev2.png
In this example there are 2 horizontal rows of blocks. Each row contains 15 blocks. 30 blocks within the scene.
Now, if we were to consider all 30 blocks one "Zone" and have 3 Zones next to each other horizontally we would have 90 blocks total. In Mich's original example, it would look like so:
Zone1===Player===Zone3
[15 tiles] [15 tiles] [15 tiles]
[15 tiles] [15 tiles] [15 tiles]
Additionally, if we were to delete Zone1 and create Zone3 as the player moved right we would be constantly rendering 60 tiles at a time.
What this image is proposing: Instead of calling big groups of tiles (Zones) only call and delete the tiles just at the edge of the scene. This would only be rendering 4 tiles simoultaneously as opposed to 60. Hopefully that is more clear.
@Doctor Fail: Thank you very much for taking the time to look into this with me. I will copy this code and give it thorough study. I am very new to T2D and just getting my head around the TorqueScript; however, it's by picking apart the logic within scripts like these that I am learning. This is very much appreciated! After I am able to review this code, I'll give feedback.
Moving forward, I have been learning more about the Composite Sprites and really it seems as though this may just be the answer for me. Regardless of prior theories here, it is all obsolete if indeed the Composite Sprites can cull the blocks outside of the scene boundaries automatically. I believe this is indeed the case. I found this old blog by Melv May introducing Composite Sprites:
www.garagegames.com/community/blogs/view/22132
In Part 3 of this blog (which is linked here) Melv details his initial goals, which in all honesty appears to be much like what I am trying to achieve:
Quote:In the end, the opportunity arrived for me to sort this out. What I did was just scrap the old tile-map and tile-layer stuff completely. After all, rendering tiles is not rocket science.
What I wanted to achieve however wasnt so easy:
Have a single scene-object that used batching and render sorting (described previously)
Have it handle thousands of sprites, each individually configurable for orientation, size, static and animated imagery, blending, scene-depth, sort-point, named etc.
Have it use Taml for persistence.
Have it allow for multiple layout modes including custom ones i.e. Rectilinear, Isometrics, Arbitrary (free-form positioning) and custom.
Allow a logical positioning system to be used to more easily address individual sprites
Allow the attachment of meta-data for each sprite
It took a little time to figure this out but with many of the system I've described previously in-place I only had to focus on how to organize this so that it was not only fast but also made sense from a TorqueScript API point-of-view.
I will continue to explore different ways to implement these blocks, both by using Composite Sprites and by starting from scratch with some sort of "Frustrum" code. Any additional insight is always welcomed, of course. Cheers, I will update here on any progress.
#13
So today I've been busy with organizing that, and am currently working on the tutorial. It will share the things I had to learn while setting up my own new project as a newcomer to T2D, and serve as a good reference.
11/12/2013 (3:14 pm)
I have taken a brief pause to write up a beginner's tutorial to setting up a new project with only a console. It's a good primer to understanding the gui and I figured since the folks here have been so helpful it is the least I could do. Practicing the golden rule of 'Do unto others' will surely only bring good things! So today I've been busy with organizing that, and am currently working on the tutorial. It will share the things I had to learn while setting up my own new project as a newcomer to T2D, and serve as a good reference.
#14
11/13/2013 (11:58 am)
Are you posting this tutorial of yours on the Github page or where are you putting it? I would find this tutorial incredibly helpful, I'm trying to understand the gui system myself, and it's been giving me quite a bit of trouble. It's great to hear that you are doing so well with it. I'm working with Doctor Fail, and it's been giving us both a rough time.
#15
Granted that the community approves of the format and delivery of this tutorial, I will continue with a 2nd part later. I am also new to the program, and all of this is just my effort to document my progress with a solid reference and reinforce what I learn as I learn it. I have not begun to move gui elements around much, and if you or Dr.Fail make any progress before I do please share! I half expect a veteran here will chime in by that time and set us all straight!
As far as GitHub, it seems like the best solution although being new to T2D I have no idea where to get started creating a blog. The tutorial is pretty much complete now. Perhaps a little proofreading is in order, but the document is there! Now I just need to find a good way of sharing it. I will probably give a stab at GitHub and have it available there soon.
11/13/2013 (4:42 pm)
Hi Andre, the tutorial I have put together details the process of getting a Console module to show up on the Canvas. It covers the overall flow of the application, and is a good primer to the gui. However, it does not go into detail about the actual gui controls used to position gui elements on the screen. The amount of information that this subject encompasses required me to break the tutorial into sections. The end of this first section gets you to the point where you understand how and why the gui is being called onto the screen, but no further. Granted that the community approves of the format and delivery of this tutorial, I will continue with a 2nd part later. I am also new to the program, and all of this is just my effort to document my progress with a solid reference and reinforce what I learn as I learn it. I have not begun to move gui elements around much, and if you or Dr.Fail make any progress before I do please share! I half expect a veteran here will chime in by that time and set us all straight!
As far as GitHub, it seems like the best solution although being new to T2D I have no idea where to get started creating a blog. The tutorial is pretty much complete now. Perhaps a little proofreading is in order, but the document is there! Now I just need to find a good way of sharing it. I will probably give a stab at GitHub and have it available there soon.
#16
11/13/2013 (6:29 pm)
This thread and the Learning the GUI thread make me so happy. The fresh blood and talk reminds me of the old days. I hope it keeps up and grows.
#17
11/14/2013 (3:20 am)
@Jesse - I really appreciate you taking the time to write up a beginners GUI tutorial. If you have difficulty finding a good way to share your guide, feel free to send me your document and images by email (address is in my profile) and I will add it to the T2D wiki on Github. That's really the best spot for it.
#18
I took a look at setting up a blog for Github last night but the process seemed to involve using Github, Jekyll, and Octopress. All of which I have never used, so that would be another learning process in and of itself.
11/14/2013 (8:56 am)
Mike: I agree the wiki would be the best place for something like this, although I wasn't aware I could contribute by sending you the information. This tutorial document imo is definately worthy of the wiki. A lot of planning went into making the information as easy to follow as possible. As soon as I get a free moment I will go ahead and proofread the document and send it to you. Thanks in advance!I took a look at setting up a blog for Github last night but the process seemed to involve using Github, Jekyll, and Octopress. All of which I have never used, so that would be another learning process in and of itself.
#19
1. fork a copy of the official wiki (when you fork the T2D repo, you also fork the wiki when you click on the wiki button in your personal T2D copy)
2. Create a page and write whatever guide I was planning.
3. Submit an issue with a link to my wiki to let the committee know a guide was available for review.
Anyone can do either the above steps or just send me a copy of your tutorial/guide by email, dropbox link, google docs link, a forum or blog post on this site, whatever. The same applies to editing an existing guide or adding additional information to one. The more we can share our knowledge as a community, the easier it is for all of us to make our games.
11/14/2013 (9:45 am)
Anyone can contribute to the official wiki - it is just not open to direct edits. Before I was on the steering committee, what I did was:1. fork a copy of the official wiki (when you fork the T2D repo, you also fork the wiki when you click on the wiki button in your personal T2D copy)
2. Create a page and write whatever guide I was planning.
3. Submit an issue with a link to my wiki to let the committee know a guide was available for review.
Anyone can do either the above steps or just send me a copy of your tutorial/guide by email, dropbox link, google docs link, a forum or blog post on this site, whatever. The same applies to editing an existing guide or adding additional information to one. The more we can share our knowledge as a community, the easier it is for all of us to make our games.
#20
11/14/2013 (11:48 am)
Thanks for this, this simplifies things a lot. I was under the impression I had to create a blog lol. I'm now proofreading the document, and I'll submit the issue once the repository page is up.
Torque Owner Stefan Lundmark
We divided the scene up into a 2D grid. We used two divisions to find out where the player was relatively, and then fetched all grid containers occupying the screen and then looped trough them.