tag:blogger.com,1999:blog-39991822583382420212024-03-18T10:47:37.802+01:00Becoming IndieAnonymoushttp://www.blogger.com/profile/16393413815766208404noreply@blogger.comBlogger79125tag:blogger.com,1999:blog-3999182258338242021.post-64110840046293067262017-07-27T21:09:00.003+02:002017-10-09T21:04:33.650+02:00Hope to see you soon (again)<div dir="ltr" style="text-align: left;" trbidi="on">
I started this blog <a href="https://becomingindiedev.blogspot.com.es/2013/04/hello-world.html" target="_blank">at the beginning of 2013</a> while finishing my ph.D. stay in Rennes (France). I did it as a self-motivation boost and because I thought it could be useful for myself to keep track of my progress and discoveries. And for some time, the effort it took to maintain the blog was really worth it. However, I must be honest to you and to myself: this blog is kind of abandoned, and I don't think this is going to change in the near future.<br />
<br />
This is why I think that the most correct action is to say goodbye. I don't intend to close or delete its contents as it contains information that can be useful either for me or for others. But I won't be writing more posts on this blog, not at least in the short term. In fact, this has already been the case for some time. During the last months, the number of posts has been decreasing and it kind of hurts me having a supposedly active blog without recent posts. I need this closure to move forward.<br />
<br />
During the time I've been writing this blog, lots of nice things have happened to me: I finished my ph.D., I published a couple of games on Android and iPhone, I co-founded a video games studio, I got married and I published my first PC game on Steam: <a href="http://store.steampowered.com/app/523870/Breaking_Fast/" target="_blank">Breaking Fast</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/r1lmJGFy6NI/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/r1lmJGFy6NI?feature=player_embedded" width="320"></iframe></div>
<br />
Now, I have nice projects ahead and I'll continue writing about game development, but I'll keep the posts in the scope of the concrete games I'll be developing by the time. <b>In particular, you'll be able to read me on <a href="https://www.talestudios.com/blog/" target="_blank">Tale Studios blog</a></b>.<br />
<br />
Thanks a lot to those of you who have been reading the posts until the very end. I hope that some of the posts gave you insight into game development and helped you in some degree.<br />
<br />
Good luck with your projects and hope to see you soon!</div>
Anonymoushttp://www.blogger.com/profile/16393413815766208404noreply@blogger.com77tag:blogger.com,1999:blog-3999182258338242021.post-17294825387922531312017-04-04T10:12:00.000+02:002017-04-04T10:12:45.237+02:00Breaking Fast at Granada Gaming 2017<div dir="ltr" style="text-align: left;" trbidi="on">
Hi! Wow, I've just noticed this is my first post in 2017, being the longest gap between posts since the blog creation. Definitely a bad record to break, although I should try to excuse myself: we're finishing up <a href="https://www.talestudios.com/breakingfast/en.html" target="_blank">Breaking Fast </a>and it's being so time-consuming... Anyway, I'll try to catch up over time.<br />
<br />
This weekend Granada Gaming has been held in Granada (Spain), a video games event that has been co-located with <a href="https://www.ficzone.com/" target="_blank">Ficzone 2017</a>, a huge event about comics, board games, cosplay and anime. The event has exceeded all the expectations and the number of visitors has been huge (although I don't know official figures yet).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-fzE4ii5O7Kg/WOKn7zLwLTI/AAAAAAAADOo/fKe_gcMYcBAe6XZ3U55eHUYRLBB8pjO2ACLcB/s1600/IMG_7952.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://3.bp.blogspot.com/-fzE4ii5O7Kg/WOKn7zLwLTI/AAAAAAAADOo/fKe_gcMYcBAe6XZ3U55eHUYRLBB8pjO2ACLcB/s320/IMG_7952.jpg" width="320" /></a></div>
<br /><span id="goog_1083716256"></span>
Of course, we've attended this event to show, one more time, <a href="https://www.talestudios.com/breakingfast/en.html" target="_blank">Breaking Fas</a>t. As usual, people have enjoyed the game quite a lot, and groups of people of all ages have played it and replayed it lots of times, pushing the limits of their friendship at times...<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-JUVDTmwbq8c/WOKoI9pWAcI/AAAAAAAADOs/-N1Uk4jRtRcwWoj2krmAbU4Bqmzdh9tAwCLcB/s1600/IMG_7942.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://1.bp.blogspot.com/-JUVDTmwbq8c/WOKoI9pWAcI/AAAAAAAADOs/-N1Uk4jRtRcwWoj2krmAbU4Bqmzdh9tAwCLcB/s320/IMG_7942.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-gXJwgBevWMc/WOKoJNlqmRI/AAAAAAAADOw/sa7CS0I3uHE0H0mHGjOgJFkc_T_nIfqHwCLcB/s1600/IMG_7953.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://3.bp.blogspot.com/-gXJwgBevWMc/WOKoJNlqmRI/AAAAAAAADOw/sa7CS0I3uHE0H0mHGjOgJFkc_T_nIfqHwCLcB/s320/IMG_7953.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-excMa5H1MVI/WOKoOpmdZOI/AAAAAAAADO0/VjSKHjvUkPASzfSVh9UYWqUiaFPVL734QCLcB/s1600/IMG_7981.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://3.bp.blogspot.com/-excMa5H1MVI/WOKoOpmdZOI/AAAAAAAADO0/VjSKHjvUkPASzfSVh9UYWqUiaFPVL734QCLcB/s320/IMG_7981.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
The whole Breaking Fast team was together in a event for the first time! </div>
<br />
On Saturday evening, there was a networking event for the indie devs (Devs&Beers) where we could talk to each other in a more relaxed environment with nice food and drinks. We had the chance to meet other devs with whom we'd already shared stand in other events, and it's a very warm feeling when you see that they continue working on their illusions in such a volatile and fragile industry in Spain. Also, we could get to know new people and projects, which is also very welcome. During this networking dinner, interesting debates arose about the state of the industry and how indie devs can overcome the barriers in the search of success.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-7MJY4ySK9Vc/WOKoYxmo5zI/AAAAAAAADO4/LCvB2zVZ94Y18uks3Qf5l4tTmEjJKfx7QCLcB/s1600/IMG_7971.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://4.bp.blogspot.com/-7MJY4ySK9Vc/WOKoYxmo5zI/AAAAAAAADO4/LCvB2zVZ94Y18uks3Qf5l4tTmEjJKfx7QCLcB/s320/IMG_7971.jpg" width="320" /></a></div>
<br />
Also, if you've never heard anything about Granada, you should probably know that it's very well known for its "tapas" (although if you're from abroad, you might think they're typical in Spain in general), mid-size plates that are served for every drink you order. And the quality of the food is up to the expectations of the Mediterranean diet, so yes, it's a good place to eat.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-4r6zImU31fg/WOKojCncy1I/AAAAAAAADPA/oDpFCngcRu0LQ5cICDe-v3co3oCbiFKOQCLcB/s1600/IMG_7969.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://2.bp.blogspot.com/-4r6zImU31fg/WOKojCncy1I/AAAAAAAADPA/oDpFCngcRu0LQ5cICDe-v3co3oCbiFKOQCLcB/s320/IMG_7969.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-AA7YMgFLr88/WOKojM7YZbI/AAAAAAAADO8/YH0jIEzrTN8pHJbM9AaJx6dmDSZgQ7RTwCLcB/s1600/IMG_7972.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://4.bp.blogspot.com/-AA7YMgFLr88/WOKojM7YZbI/AAAAAAAADO8/YH0jIEzrTN8pHJbM9AaJx6dmDSZgQ7RTwCLcB/s320/IMG_7972.jpg" width="320" /></a></div>
<br />
One of the celebrities invited to Granada Gaming was Akira Yamaoka, who is a composer famously known for his work on <a href="https://www.youtube.com/watch?v=w2cK8mOG4Q8" target="_blank">Silent Hill</a>. As part of the networking program, we developers had a group meeting with him in which we could ask him whatever we wanted to know. One of my questions was about how to commercialize a game like Breaking Fast in Japan once it's localized in this language. He told me that he thought this game could sell well in Japan and advised me to partner with a breakfast food company to gain visibility.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-hHF3oqOJhxc/WONRj61L5FI/AAAAAAAADPU/Cl-IXDfICvkAGDPKLz0SjKndnNbVd_RMgCLcB/s1600/IMG_7978.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://3.bp.blogspot.com/-hHF3oqOJhxc/WONRj61L5FI/AAAAAAAADPU/Cl-IXDfICvkAGDPKLz0SjKndnNbVd_RMgCLcB/s320/IMG_7978.jpg" width="320" /></a></div>
<br />
As a final anecdote, there was a girl who attended the event wearing the official t-shirt of Breaking Fast! She had participated in one of the contests we organized in previous events and she had won. And there she was, exhibiting with pride this t-shirt while playing Breaking Fast. This was a really awesome moment for us!</div>
Anonymoushttp://www.blogger.com/profile/16393413815766208404noreply@blogger.com21tag:blogger.com,1999:blog-3999182258338242021.post-42754195879294232062016-12-31T12:15:00.004+01:002016-12-31T12:15:41.369+01:00Becoming Indie Developer: A 2016 Retrospective<div dir="ltr" style="text-align: left;" trbidi="on">
Hi buddies!<br />
<br />
I still remember it as if it was yesterday when I started this blog. It was April 2013 and I was doing my Ph.D. stay in Rennes, France. By that time, I was a full-time researcher at the University of Malaga and my main goal was to finish my stay, write my last journal articles and defend my Ph.D. However, for a very long time I had had an itch for making games.<br />
<br />
My experience with games development started surprisingly early, when I was around 14 years old. By that time, my grandfather, who knew how much I wanted to learn this stuff, gave me a <a href="https://www.thegamecreators.com/product/dark-basic-pro-open-source" target="_blank">Darkbasic</a> pack as a birthday present. I still remember how, during high school classes, I would daydream about the amazing games I was about to make. I can perfectly remember thinking to myself about making a Matrix-style game where the main character would avoid bullets bending over himself, just like Neo, and I would naively think that it wouldn't take me long to reach such level of expertise. Of course, reality imposed itself, and there were so many new terms I had no clue about, that it took me a long time to just make a Pong clone (with some additional cool features like moving obstacles).<br />
<br />
By that time and until finishing high school I made some very simple games, and when I started the Computer Science degree at the University, the demanding subjects drifted me away from my dream. Yet I still read about games programming and with the new knowledge acquired I could understand more and more about how a videogame is built from the ground-up. Life circumstances (which were really driven by luck and momentum, as they usually are) geared me to start working in the Computer Science department, where I would take a 4 years Ph.D. grant after finishing the degree. Over this period, I overlapped my Ph.D. with the creation of small video games: in 2014, I released <a href="https://itunes.apple.com/es/app/chubby-buddy/id823823086?mt=8" target="_blank">Chubby Buddy</a> on iOS, and in 2015, Limball on <a href="https://itunes.apple.com/es/app/id882244191" target="_blank">iOS</a> and <a href="https://play.google.com/store/apps/details?id=nonisoft.limball" target="_blank">Android </a>(both of them together with <a href="https://twitter.com/ManuelaRMontiel" target="_blank">Manuela</a>).<br />
<div>
<br /></div>
All that time was a great experience and I don't regret any of the choices I made, but the truth is that the moment of making games <i>for real</i> never seemed to come. And this is where, during the Ph.D. stay, I made my decision: I would finish my Ph.D., but right after doing so, I would quit research and become full-time game developer. And creating this blog was the first step towards convincing myself of walking down this risky and uncertain path...<br />
<br />
And here I am now, after one year, I can really claim that I have become an indie game developer, doing justice to the name of the blog. I wish I could add that it's been a profitable decision, but I cannot claim that, not at least for now. I'm currently finishing <a href="http://www.talestudios.com/breakingfast/" target="_blank">Breaking Fast</a>, which I've been developing (together with <a href="https://twitter.com/ManuelaRMontiel" target="_blank">Manuela</a>, as usual, but also with <a href="https://twitter.com/Oli_mus" target="_blank">Oliver </a>and <a href="https://twitter.com/David_Mariscal" target="_blank">David</a>) for almost a year and which we've financed with the savings accumulated over the aforementioned years of working in the research area. During this time, I've observed some things I want to mention now.<br />
<br />
<b>Cool things or things that I think we've done alright</b><br />
<br />
One of the typical problems of unexperienced game developers is delaying the marketing actions to the release date. I think I can clearly claim that we haven't made such mistake. From the very first moment we had a playable version of the game, we attended game events to show it and receive feedback from players. In our case, our first event was <a href="https://becomingindiedev.blogspot.com.es/2016/05/a-brief-pax-east-2016-post-mortem.html" target="_blank">PAX East</a> (not bad to be the first one, uh?), and from that event, which took place in April, we have attended more than 10 events over the year. As for marketing in social networks, we have populated our accounts with new contents nearly every day since we started. Believe us: all of this (events and social networks) is a huge amount of work. We estimate that around 50-60% of the time has been devoted to these activities, leaving the 40-50% remaining time to the actual development of the game. The conclusion we draw is the following: if you have the resources, hire someone to manage all this stuff (especially, your social networks).<br />
<br />
Another thing we did alright was to establish and adhere to a work routine. This is especially important when you work from home, as we do. We would set weekly goals and monitor whether we fulfill those goals. The only setback is that sometimes we finished working too late, precisely because the border between our personal and professional lives became fuzzy as a consequence of working from home.<br />
<br />
<b>Difficulties</b><br />
<br />
Now I want to mention some things that have been difficult for us. First, and as I mentioned before, PR and marketing are really time-consuming activities, especially because we had to learn on the go lots of stuff: how to write press releases, how to find our target audience, how to connect emotionally with such audience, etc.<br />
<br />
Our initial plans was to keep this blog and our Youtube profile updated with fresh contents but it hasn't been possible. Maintaining a development blog is a tough work, especially if you're interested in writing about technical details of the development, which requires beforehand planning. In the end, I've basically written some posts about the events we have attended, but that is not what the blog was meant for initially. Something similar has happened to our Youtube profile: creating and editing videos is a harder activity than we had anticipated.<br />
<br />
<b>Things to improve</b><br />
<br />
We have identified some things that we should improve either in the next year or in future projects. First, we intend to choose events with more criteria in the future. Attending so many events as we have this year has been a great experience in many aspects, but they require money and time (preparing the material, booking the flights and hotel, etc). In relation to this, we also failed to make some time predictions correctly because we didn't factor in the time of these events appropriately. This is the reason why we first scheduled the release of Breaking Fast in the end of 2016, but we've had to put it off by the beginning of Spring 2017...<br />
<br />
Also, although from the very beginning we had built a contact list, we didn't use it until very recently, which has been a wasted opportunity to engage with our potential customers sooner. Sending newsletters is an important activity that we should have started much earlier.<br />
<br />
Although we can state that we are more or less well-known in Spain, with several articles in different specialized media, we fail to be known outside Spain. And this is a real problem because most of our sales are expected to be made abroad, especially in USA and Russia. Therefore, one of the goals for the beginning of the year is to contact these international media in order to raise a wide awareness of Breaking Fast.<br />
<br />
Finally, I leave you with a video summary of our 2016:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe width="320" height="266" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/y2-qQwF8YHE/0.jpg" src="https://www.youtube.com/embed/y2-qQwF8YHE?feature=player_embedded" frameborder="0" allowfullscreen></iframe></div>
<br />
Thanks for being there and reading these posts. We really wish you a happy 2017: the year of Breaking Fast! :D</div>
Anonymoushttp://www.blogger.com/profile/16393413815766208404noreply@blogger.com9tag:blogger.com,1999:blog-3999182258338242021.post-66592250186196071572016-10-17T15:18:00.000+02:002016-10-17T15:18:47.124+02:00Gamepolis Indie Zone: A Summary<div dir="ltr" style="text-align: left;" trbidi="on">
Hi folks!<br />
<br />
It's been too long since the last post, so first things first: sorry about the delay. As you may know, we're working hard to meet several deadlines with our game <a href="https://becomingindiedev.blogspot.com.es/2016/07/breaking-fast-on-steam-greenlight.html" target="_blank">Breaking Fast</a>, about which I'll write something more technically-oriented soon.<br />
<br />
By the end of July we attended <a href="http://www.gamepolis.org/web/" target="_blank">Gamepolis</a>. But <a href="http://becomingindiedev.blogspot.com.es/2015/07/gamepolis-2015-overview.html" target="_blank">unlike in the previous years</a> in which we participated as general audience, this year we were presenting our own game: <a href="http://www.talestudios.com/breakingfast/index_en.html" target="_blank">Breaking Fast.</a><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-MMusJqo0nlQ/V_z3T-aLcSI/AAAAAAAADLI/7oB5pFYeL-Ql3BY-XmCA2vRYXD4hxEwNgCEw/s1600/IMG_6190.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://4.bp.blogspot.com/-MMusJqo0nlQ/V_z3T-aLcSI/AAAAAAAADLI/7oB5pFYeL-Ql3BY-XmCA2vRYXD4hxEwNgCEw/s320/IMG_6190.jpg" width="320" /></a></div>
<div style="text-align: center;">
Our stand at Gamepolis. From right to left, <a href="http://olivermoyabueno.com/" target="_blank">Óliver</a>, <a href="https://twitter.com/ManuelaRMontiel" target="_blank">Manuela </a>and <a href="https://twitter.com/francismoy" target="_blank">myself</a></div>
<br />
The Indie Zone, which was located close to the entry doors, consisted of a circular area in which 16 indie studios were showcasing their games, most of them, if not all, still in development. As usual, the two main benefits of attending an event like Gamepolis, which is targeted at a broad audience, are obtaining feedback and raising awareness of your game, and getting to know other professionals who have the same dreams and aspirations as us. As for the last point, we're very happy that we could meet the developers of great games like <a href="http://cubotrox.com/" target="_blank">Cubotrox</a>, <a href="http://catnessgames.com/#hive" target="_blank">Hive</a>, <a href="https://www.facebook.com/noahmund/?ref=ts&fref=ts" target="_blank">Noahmund</a>, <a href="http://es.ign.com/gamepolis-2016/106241/video/gamepolis-2016-entrevista-crimson-breath" target="_blank">Crimson Breath</a> or <a href="http://www.8bitamin.com/blog/" target="_blank">Charlie Beard</a>, among others. We even went out for a dinner one night after the show!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-OD9zj19pV9Q/V_z3L3T6qoI/AAAAAAAADKk/vWnmhDGhHG4FZ9iNVEG5qzAzQHLXEWLSQCEw/s1600/IMG_6214.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://1.bp.blogspot.com/-OD9zj19pV9Q/V_z3L3T6qoI/AAAAAAAADKk/vWnmhDGhHG4FZ9iNVEG5qzAzQHLXEWLSQCEw/s320/IMG_6214.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-QWw96OiT5Gs/V_z3Mxgl4uI/AAAAAAAADKo/4m5vsnzsNIMw83p3IhRhZRBgz-OKtRiFwCEw/s1600/IMG_6220.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://3.bp.blogspot.com/-QWw96OiT5Gs/V_z3Mxgl4uI/AAAAAAAADKo/4m5vsnzsNIMw83p3IhRhZRBgz-OKtRiFwCEw/s320/IMG_6220.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-ltICvEA241U/V_z3L0C9ZFI/AAAAAAAADKg/H-UKse6sYFEujiKVu9J6rp-IupG4D_68ACEw/s1600/IMG_6236.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://3.bp.blogspot.com/-ltICvEA241U/V_z3L0C9ZFI/AAAAAAAADKg/H-UKse6sYFEujiKVu9J6rp-IupG4D_68ACEw/s320/IMG_6236.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-5JCESzH3h90/V_z3My0qGOI/AAAAAAAADKw/OZAHX2RPJdMM53LpGyJ6IDC_x3xqilf4ACEw/s1600/IMG_6238.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://2.bp.blogspot.com/-5JCESzH3h90/V_z3My0qGOI/AAAAAAAADKw/OZAHX2RPJdMM53LpGyJ6IDC_x3xqilf4ACEw/s320/IMG_6238.jpg" width="320" /></a></div>
<div style="text-align: center;">
Pictures with some of the other studios that participated in Gamepolis</div>
<br />
The other advantage of participating in this event, that is, exposing your game to a big audience, turned out a fantastic experience. People of all ages (although especially kids and teenagers) would play for a really long time, and they'd come back later bringing more friends to show that <i>'crazy game with breakfast food</i>'.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-al_MfiXIVSo/V_z3UL3k1-I/AAAAAAAADLg/bpEC41m0QIw8oY1FKBw6jcrbySwbA1UiACEw/s1600/IMG_6191.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://4.bp.blogspot.com/-al_MfiXIVSo/V_z3UL3k1-I/AAAAAAAADLg/bpEC41m0QIw8oY1FKBw6jcrbySwbA1UiACEw/s320/IMG_6191.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-t0h2GnWMdbc/V_z3UhXu1PI/AAAAAAAADLg/jBbXCxdUt28pdYSSQuV_xi3fhYvdHFoWACEw/s1600/IMG_6195.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://4.bp.blogspot.com/-t0h2GnWMdbc/V_z3UhXu1PI/AAAAAAAADLg/jBbXCxdUt28pdYSSQuV_xi3fhYvdHFoWACEw/s320/IMG_6195.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-CDeBi1_hWN4/V_z3Uqp3meI/AAAAAAAADLg/pRuUNkUSpUIzlmk3-bOujZrvuLBM3vdfACEw/s1600/IMG_6199.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://3.bp.blogspot.com/-CDeBi1_hWN4/V_z3Uqp3meI/AAAAAAAADLg/pRuUNkUSpUIzlmk3-bOujZrvuLBM3vdfACEw/s320/IMG_6199.jpg" width="320" /></a></div>
<div style="text-align: center;">
People enjoying the Breaking Fast experience. <a href="https://www.locomalito.com/" target="_blank">Locomalito </a>and <a href="https://twitter.com/Gryzor87" target="_blank">Gryzor</a> also enjoyed it!</div>
<br />
We even organized a tournament in which the best three players would win an <a href="http://www.latostadora.com/talestudios" target="_blank">official Breaking Fast tee</a>. The initiative was really welcome, and hundreds of participants signed up for it. Knowing potential fans of your game is very rewarding, and we took a good deal of pictures with them. Some of them covered Breaking Fast on <a href="https://www.youtube.com/watch?v=6-X0h0pZFYE" target="_blank">their Youtube channels</a>, which is something that we, as indie developers, always appreciate a lot.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-B1pDv4IO0kU/V_z3M8KHwsI/AAAAAAAADLg/PSFUBnC18Xo532uQUcukc5tDabeH4iSawCEw/s1600/IMG_6212.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://3.bp.blogspot.com/-B1pDv4IO0kU/V_z3M8KHwsI/AAAAAAAADLg/PSFUBnC18Xo532uQUcukc5tDabeH4iSawCEw/s320/IMG_6212.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-yROf_yV-w-0/V_z3NU65AjI/AAAAAAAADLg/GR7HA2LzI9Erw5R3eFuhWe9RP7qiH89mQCEw/s1600/IMG_6226.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://4.bp.blogspot.com/-yROf_yV-w-0/V_z3NU65AjI/AAAAAAAADLg/GR7HA2LzI9Erw5R3eFuhWe9RP7qiH89mQCEw/s320/IMG_6226.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-963ZOEtbMSE/V_z3NT_DO6I/AAAAAAAADLg/VGByTHq3E9gv27xXsrn9KvtLz6f7qufUQCEw/s1600/IMG_6228.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://3.bp.blogspot.com/-963ZOEtbMSE/V_z3NT_DO6I/AAAAAAAADLg/VGByTHq3E9gv27xXsrn9KvtLz6f7qufUQCEw/s320/IMG_6228.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-paxajUSI5U0/V_z3NlwMt5I/AAAAAAAADLg/TOhsYdAR4_4r-CyQfXrNNQ75bB6qFE_CQCEw/s1600/IMG_6233.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://1.bp.blogspot.com/-paxajUSI5U0/V_z3NlwMt5I/AAAAAAAADLg/TOhsYdAR4_4r-CyQfXrNNQ75bB6qFE_CQCEw/s320/IMG_6233.jpg" width="320" /></a></div>
<div style="text-align: center;">
Some of our more loyal fans. Thanks so much!</div>
<br />
Finally, as part of the participation, we were eligible for different awards, and good news are... <b>we won the Public Choice Award</b>! Even when the economic value of the award cannot be dismissed for a low-budget studio, the real value comes in the form of motivation and inspiration to continue improving the game. <b>It's a certainty right now that people enjoy Breaking Fast, and enjoy it a lot. It's just a matter of polishing it well</b>. The other awards went to Noahmund (best sound), Hive (best game as chosen by the jurors), Crimson Breath (best visuals) and Cubotrox (most innovative game). <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-GEef11zXpxk/V_z3QhY-mSI/AAAAAAAADLg/ynMQjkb6Tzki5hg97uBrn0y8am0i8jAJgCEw/s1600/IMG_6224.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://2.bp.blogspot.com/-GEef11zXpxk/V_z3QhY-mSI/AAAAAAAADLg/ynMQjkb6Tzki5hg97uBrn0y8am0i8jAJgCEw/s320/IMG_6224.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-dC7S2u-uu1s/V_z3QdqrUFI/AAAAAAAADLg/PLonsoxof20j-l-ZoEZfLWS57jk04_cEgCEw/s1600/IMG_6225.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://4.bp.blogspot.com/-dC7S2u-uu1s/V_z3QdqrUFI/AAAAAAAADLg/PLonsoxof20j-l-ZoEZfLWS57jk04_cEgCEw/s320/IMG_6225.jpg" width="180" /></a></div>
<br />
<br />
If you want to read something very cool (and deep) about Gamepolis and about the indie scene in general, <a href="http://www.elpixelilustre.com/2016/07/videojuegos-indie-gamepolis.html" target="_blank">check this out </a>(in Spanish, sorry).<br />
<br />
See you! </div>
Anonymoushttp://www.blogger.com/profile/16393413815766208404noreply@blogger.com3tag:blogger.com,1999:blog-3999182258338242021.post-91649087855916347452016-08-17T16:00:00.000+02:002016-08-17T16:00:07.632+02:00Mallorca Game and Gamelab 2016<div dir="ltr" style="text-align: left;" trbidi="on">
I want to discuss today our experience during two videogames events that we had by the end of June: <a href="http://www.mallorcagame.es/" target="_blank">Mallorca Game</a> and <a href="http://www.gamelab.es/2016/" target="_blank">Gamelab</a>. These two events are very different from each other, with the former being targeted at a broader audience, and the latter oriented towards professional game developers.<br />
<b><br /></b>
<b>Mallorca Game</b><br />
<br />
The fourth edition of this event brought a big deal of attention from gamers and cosplayers. It was a two-days event where people could buy almost anything you can imagine from the videogames and manga worlds, and where we, the indie game developers, could showcase our game. We had a long table with enough space to set up everything we needed to present our game Breaking Fast. We hung some posters, prepared our monitor and four controllers, and laid some promotional material on the table, such as flyers and business cards.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-4XDJbzOJ2ho/V6Ri2koHxAI/AAAAAAAADH8/MHzkJhHWVPkXlsRwJ02h6y_QPX5AGdV6gCLcB/s1600/IMG_6014.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://4.bp.blogspot.com/-4XDJbzOJ2ho/V6Ri2koHxAI/AAAAAAAADH8/MHzkJhHWVPkXlsRwJ02h6y_QPX5AGdV6gCLcB/s320/IMG_6014.jpg" width="320" /></a></div>
<br />
We didn't expect such a big audience, and again like in Boston and Cartagena, the feedback was really valuable and positive. People from all ages played our game and especially some kids wouldn't let go the controller for a (too) long period of time.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-HVnZfcFZamA/V6RkNyAveEI/AAAAAAAADIU/ZQeyLkBZ-wEcwln9MpLiEaPQZPhAAVHegCLcB/s1600/IMG_6031.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://2.bp.blogspot.com/-HVnZfcFZamA/V6RkNyAveEI/AAAAAAAADIU/ZQeyLkBZ-wEcwln9MpLiEaPQZPhAAVHegCLcB/s320/IMG_6031.jpg" width="320" /></a></div>
<br />
As part of the event, there were three awards to the three best indie games that were presented at the so-called Mallorca Game Awards. In the gala ceremony, which was held during the last day, we were awarded with the second prize to the best indie game.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-Jjjh7xbKYPE/V6Ri3_YyagI/AAAAAAAADIA/UV0ncxpJJXwExDoouMJ5wRpBCkP8sYqIwCLcB/s1600/recogidaPremio.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="https://4.bp.blogspot.com/-Jjjh7xbKYPE/V6Ri3_YyagI/AAAAAAAADIA/UV0ncxpJJXwExDoouMJ5wRpBCkP8sYqIwCLcB/s320/recogidaPremio.jpg" width="320" /> </a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
We were 'snatched' the first prize by <a href="https://steamcommunity.com/sharedfiles/filedetails/?id=654467376" target="_blank">Cubotrox</a>, an amazing and innovative puzzle game created by two twin brothers from Valencia that we got to meet, coincidentally, at Gamelab.<br />
<br />
As usual in our trips, we took some time off in order to visit Mallorca and enjoy really nice food.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-n3WAwDsk4h8/V6RkG6-WWlI/AAAAAAAADIM/TZnE074BmE8BF2sColVv_NmUEKwZSLkXwCLcB/s1600/IMG_6013.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://1.bp.blogspot.com/-n3WAwDsk4h8/V6RkG6-WWlI/AAAAAAAADIM/TZnE074BmE8BF2sColVv_NmUEKwZSLkXwCLcB/s320/IMG_6013.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-CJd099ZZjT8/V6RkHBSFtXI/AAAAAAAADIQ/fD_ov1TslUw8g76IlxXiINYot4Sx_VXJwCLcB/s1600/IMG_6034.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://4.bp.blogspot.com/-CJd099ZZjT8/V6RkHBSFtXI/AAAAAAAADIQ/fD_ov1TslUw8g76IlxXiINYot4Sx_VXJwCLcB/s320/IMG_6034.jpg" width="320" /></a></div>
<br />
<b>Gamelab</b><br />
<br />
As I mentioned before, whereas Mallorca Game was targeted at a broad audience, Gamelab was very focused on professional game developers. Actually, the number of attendants seemed to be lower than at Mallorca Game, and the quality of the conferences was amazing (e.g. John Romero...).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-GB0b20XsDQY/V6Rlf9kZ9CI/AAAAAAAADIk/YtyPIvgQq64CI0hXy-b0_u8nKuF6QgXwQCLcB/s1600/IMG_6089.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://3.bp.blogspot.com/-GB0b20XsDQY/V6Rlf9kZ9CI/AAAAAAAADIk/YtyPIvgQq64CI0hXy-b0_u8nKuF6QgXwQCLcB/s320/IMG_6089.jpg" width="320" /></a></div>
<br />
The feedback that we gained was more polished and concrete, although not so many people played Breaking Fast. David Mariscal, who is collaborating with us, came to help us out.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-FGXq3EKx-EU/V6Rlf7nOMDI/AAAAAAAADIg/pYXEo0bcSk4lZOt6Ovz6qNGYmCJntdY8QCLcB/s1600/IMG_6084.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://2.bp.blogspot.com/-FGXq3EKx-EU/V6Rlf7nOMDI/AAAAAAAADIg/pYXEo0bcSk4lZOt6Ovz6qNGYmCJntdY8QCLcB/s320/IMG_6084.jpg" width="320" /></a></div>
<br />
While in Mallorca we had a long table for us (actually more space than we actually needed), at Gamelab the space was too narrow. Being a multiplayer game, it was kind of annoying when four players wanted to play together, as they'd have to stand too close to each other and still they would take part of the space from the indie games to our right and left. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-1QSaMCfPI04/V6Rlfy0rrFI/AAAAAAAADIo/Bp4508xe9vgtYyW0BdNjZxwR0yVE8boBwCLcB/s1600/IMG_6087.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://1.bp.blogspot.com/-1QSaMCfPI04/V6Rlfy0rrFI/AAAAAAAADIo/Bp4508xe9vgtYyW0BdNjZxwR0yVE8boBwCLcB/s320/IMG_6087.jpg" width="320" /></a></div>
<br />
One of the main benefits of attending an event of recognized prestige like Gamelab (in addition to the feedback) is the possibility of networking with other important indie teams and professionals of different videogames-related areas. And this networking does not boil down to talking during the event, but also after the official time. In particular, a party was organized in a cottage with a big swimming-pool and free beer.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-8Fj1LxQtobQ/V6RlgTDXQYI/AAAAAAAADIs/47yYlfQ9SPE3XsrUGNeNbJFpvWb1oIcZwCLcB/s1600/IMG_6110.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://1.bp.blogspot.com/-8Fj1LxQtobQ/V6RlgTDXQYI/AAAAAAAADIs/47yYlfQ9SPE3XsrUGNeNbJFpvWb1oIcZwCLcB/s320/IMG_6110.jpg" width="320" /></a></div>
<br />
Two guys from Machinima SBOC, with whom we had the chance to talk, wanted to record the event live (but they finally couldn't because there was no Wi-Fi available). Yet they made a couple of videos about their experiencie at Gamepolis and they played our game, Breaking Fast! :D<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/a-6nhvjAn9M/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/a-6nhvjAn9M?feature=player_embedded" width="320"></iframe></div>
<br />
As I said before, we met Cubotrox makers, and although we didn't
know them by that time, we would meet them later at Gamepolis (more on this
in the following post). You can take a look at other great indie games presented at Gamelab <a href="http://www.gamelab.es/2016/indie-hub/" target="_blank">here</a>.</div>
Anonymoushttp://www.blogger.com/profile/16393413815766208404noreply@blogger.com1tag:blogger.com,1999:blog-3999182258338242021.post-4317087992352847442016-07-08T10:30:00.000+02:002016-07-08T10:40:32.736+02:00Game Loops with Fixed Simulation Steps<div dir="ltr" style="text-align: left;" trbidi="on">
Hi!<br />
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Today I want to talk about game loops. If you're a game developer, you surely know what a game loop is. However, let me summarize it with the following image:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-2kpvA_i-DEA/V3vo874L3uI/AAAAAAAADF4/2ODAebnnuvEyDuQjSqVfcfcbPseDx7lWwCLcB/s1600/game-loop-simple.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="104" src="https://3.bp.blogspot.com/-2kpvA_i-DEA/V3vo874L3uI/AAAAAAAADF4/2ODAebnnuvEyDuQjSqVfcfcbPseDx7lWwCLcB/s320/game-loop-simple.png" width="320" /></a></div>
<div style="text-align: center;">
Figure 1. Traditional Game Loop (from <a href="http://gameprogrammingpatterns.com/">http://gameprogrammingpatterns.com</a>)</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
A game loop is basically a sequence of instructions that is repeated continously from the beginning to the end of the game and which is in charge of interpreting input, simulating the world and rendering the world on screen. Very often, there is a 1:1 mapping between the concept of <i>frame</i>, and one execution of the loop, because a frame of the game is rendered each execution of the loop. However, this doesn't need to be the case and you can have different frame rates for the rendering function and for the simulation function. In fact, a common approach in sophisticated, simulation-intensive games is to fix the timestep of the simulation function in order to achieve predictable and deterministic behaviour of the simulation. Meanwhile, the render function is executed as fast as it can run, leading to a higher, variable display rate. You can read more about this decoupling in the following eye-opener posts:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
[1] <a href="http://gafferongames.com/game-physics/fix-your-timestep/" target="_blank">Fix your timestep</a></div>
<div style="text-align: justify;">
[2] <a href="http://kirbysayshi.com/2013/09/24/interpolated-physics-rendering.html" target="_blank">Interpolated Physics Rendering</a></div>
<div style="text-align: justify;">
[3] <a href="http://www.koonsolo.com/news/dewitters-gameloop/" target="_blank">deWITTERS Game Loop</a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I actually encourage you to read the previous posts (especially the first one) before continuing reading. Otherwise, this post may be difficult to follow.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I had the idea of writing this article because I tried to use the technique suggested in [1] with no success. After failing, I skimmed through the comments of the post and I found two comments (by Nick and Voy) which basically stated that although the technique was really valuable, the implementation suffered an off by one error, which resulted in no simulation step taken at all. This was in fact the problem I was having (entities of the game weren't moving), and therefore I set out to fix it for educational purposes.<br />
<br />
Before showing the actual code, let me illustrate with figures how we want the simulation to happen:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-iCUFZwQgZw8/V31QNEnIwcI/AAAAAAAADHE/zSrubUHcQagmQkRId-06ydPW97-b6UInACLcB/s1600/gameTime1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="81" src="https://3.bp.blogspot.com/-iCUFZwQgZw8/V31QNEnIwcI/AAAAAAAADHE/zSrubUHcQagmQkRId-06ydPW97-b6UInACLcB/s320/gameTime1.png" width="320" /></a></div>
<div style="text-align: center;">
Figure 2</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-HpAEd5zNWJI/V31QNA0CNcI/AAAAAAAADHM/E-hKUh62pPk9LAuaLdHt6_d3CsJCd8sNQCLcB/s1600/gameTime2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="101" src="https://3.bp.blogspot.com/-HpAEd5zNWJI/V31QNA0CNcI/AAAAAAAADHM/E-hKUh62pPk9LAuaLdHt6_d3CsJCd8sNQCLcB/s320/gameTime2.png" width="320" /></a></div>
<div style="text-align: center;">
Figure 3</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-ylRh3AdMfZM/V31QNEb5rfI/AAAAAAAADHI/8We0SjApfrkcslFBHebry1v4IM4CsttnQCLcB/s1600/gameTime3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="99" src="https://4.bp.blogspot.com/-ylRh3AdMfZM/V31QNEb5rfI/AAAAAAAADHI/8We0SjApfrkcslFBHebry1v4IM4CsttnQCLcB/s320/gameTime3.png" width="320" /></a></div>
<div style="text-align: center;">
Figure 4</div>
<div style="text-align: center;">
<br /></div>
Figure 2 shows that we divide the time of the game in discrete chunks of the same size. Don't let the concrete numbers fool you: you'll typically want the simulation to take small steps (say 0.01 seconds) in order to reduce numerical errors. The point is that there are concrete, fixed moments over the life of the game at which we want to simulate the world, and we DON'T want to simulate at any other moments between those.<br />
<br />
For instance, let's assume that the time is somewhere between the beginning of the game (0) and the first moment at which we want to simulate (1). This corresponds to what Figure 3 shows. The green arrows show different game times at which we can be, whereas the red arrow shows the point that we actually want to simulate for these times. Notice that while we're between point 0 and 1, we simulate at time 1. Similarly, as illustrated in Figure 4, while we are between moments 1 and 2, we want the simulation of time 2. And so on.<br />
<br />
At this point, you might be thinking that this is somewhat incorrect, right? Because this wouldn't produce a smooth movement, as we're treating many different times the same way. That is, the position (and velocities) of objects shouldn't be the same for every time value between 0 and 1. If we're on time 0.2 and then the game advances to time 0.5, you want the objects of the game to move a little bit. However, with what I've just told you up to now, objects wouldn't move until the time of the game advances past 1, at which point we would make another simulation.<br />
<br />
This is when interpolation comes into play. The key of the approach is the following: we simulate the future and we interpolate proportionally to the distance to this future. Therefore, if we're on time 0.2, we're further away from the future than if we're on time 0.8. The closer to the future, the closer to the simulation. We can achieve this with a linear interpolation in which an <i>alpha </i>value determines how close we're to the future:<br />
<br />
<div style="text-align: center;">
<i>position = position * (1 - alpha) + futurePosition * alpha, 0 <= alpha <= 1</i></div>
<br />
Without further ado, here's the C++/<a href="http://www.sfml-dev.org/" target="_blank">SFML</a> code for the simulation:<br />
<br />
<pre style="background: #f0f0f0; border: 1px dashed #cccccc; color: black; font-family: "arial"; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> //Initialization (out of the loop)
const auto dt = sf::seconds(0.01f);
auto accumulator = sf::Time::Zero;
auto lastTimeUpdated = 1;
MotionSystem::SimulateFuture(dt.asSeconds(), futurePos, futureVel);
//In game loop
accumulator += elapsedTime;
double timesDt;
const auto fractionToNextFrame = modf(accumulator / dt, &timesDt);
if ((timesDt + 1) > lastTimeUpdated)
{
for (uint16_t i = lastTimeUpdated; i < timesDt + 1; ++i)
{
MotionSystem::SimulateFuture(dt.asSeconds(), futurePos, futureVel);
}
lastTimeUpdated = timesDt + 1;
}
MotionSystem::Interpolate(fractionToNextFrame, futurePos, futureVel);
</code></pre>
<br />
The accumulator variable holds the time that has passed since the game started. Then, by using the C++ function <i>modf</i>, we can extract how many times <i>dt </i>has passed and how close we are to the next frame.<br />
<br />
Note that before entering the loop, we have made the first simulation,
the one corresponding to the first point in time at which we want to
simulate. That is, we have simulated the first point in the future and <i>lastTimeUpdated </i>is assigned this information.<br />
<br />
Let's lay out an example: consider that the first time the loop executes, <i>accumulator = 0.004</i>. Being <i>dt = 0.01</i>, we're almost halfway between the present and the simulated future. Given that <i>accumulator / dt = 0.4</i>, after the execution of <i>modf</i>, the variable <i>timesDt = 0</i>, and <i>fractionToNextFrame = 0.4</i>. The <i>if</i> condition is not met, and therefore no simulation is performed. We interpolate the current position with the future position according to <i>fractionToNextFrame</i> when we call <i>MotionSystem::Interpolate</i>. Internally, this function does something like the following:<br />
<br />
<i> </i><br />
<div style="text-align: center;">
<i>position = position * 0.6 + futurePosition * 0.4</i></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Let's assume that in the following execution of the loop,<i> accumulator = 0.018</i>. Now, <i>timesDt = 1 </i>and <i>fractionToNextFrame = 0.8</i>. The <i>if</i> condition is now met (<i>2 > 1</i>) and in the <i>for </i>loop, we make one simulation of the future, reaching the second simulation point, and updating <i>lastTimeUpdated = 2</i>. Finally, we interpolate as follows:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: center;">
<i>position = position * 0.2 + futurePosition * 0.8</i></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
In case there's a frame drop or the rendering function (which would be executed after this simulation) takes too long, the simulation can catch up in a controlled way because it will be executed all the times it is required in a fixed timestep. You can work out the numbers yourself considering a sudden <i>accumulator = 0.12</i>.<i> </i></div>
<div style="text-align: justify;">
<br /></div>
</div>
<div style="text-align: justify;">
Hope you liked this post. If you notice that something is missing or that I made any mistake, let me know so that I can fix it.<br />
<br />
See you!</div>
</div>
Anonymoushttp://www.blogger.com/profile/16393413815766208404noreply@blogger.com5tag:blogger.com,1999:blog-3999182258338242021.post-11315541907490591262016-07-06T11:52:00.001+02:002016-07-18T14:07:12.950+02:00Breaking Fast on Steam Greenlight!<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
Hi buddies!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Breaking Fast is now on <a href="http://steamcommunity.com/sharedfiles/filedetails/?id=698541028" target="_blank">Steam Greenlight</a>! I already wrote about <a href="http://becomingindiedev.blogspot.com.es/2015/10/angry-milk-and-cookies-this-is-breaking.html" target="_blank">this game several posts ago</a>, but here's a quick summary: Breaking Fast is a 2D racing game in which the main characters are pieces of breakfast food, like a toast, a carton of milk or a strip of bacon. Following the lines of masterpieces of fun like Mario Kart, Breaking Fast proposes frenetic races in delicious scenarios like a kitchen or a picnic. During these races, it's not only a matter of being faster: you also need to be smarter and stronger, because you have to avoid obstacles (all food-related) and the attacks from other players.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-P8KhkCSTjTQ/V3zTVjE9JDI/AAAAAAAADGo/PHBKUnbnd5wYaO-QNEi7wJ3LQXhR00AVACLcB/s1600/Tale%2BStudios%2B-%2BBreaking%2BFast%2BVery%2BSmall%2BEnglish.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://2.bp.blogspot.com/-P8KhkCSTjTQ/V3zTVjE9JDI/AAAAAAAADGo/PHBKUnbnd5wYaO-QNEi7wJ3LQXhR00AVACLcB/s320/Tale%2BStudios%2B-%2BBreaking%2BFast%2BVery%2BSmall%2BEnglish.png" width="320" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The game will come out by the end of 2016. We're working on lots of stuff: polishing animations, creating new scenarios and characters, and on an online mode. Also, we collected a good deal of feedback from users and developers at both <a href="http://www.mallorcagame.es/" target="_blank">Mallorca Game</a> and <a href="http://www.gamelab.es/2016/" target="_blank">Gamelab</a> (more about them in future posts), and we'll try to incorporate the best ideas to enhance the gameplay experience.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
By the way, we're also very proud that we won the 2nd prize in the Mallorca Game Awards! But as I just mentioned, I'll give more details about this in future posts. </div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-LgcHEiQSZ8c/V3zUozp3udI/AAAAAAAADG0/PpgUxcn-Bxk3gGyw4DqEmrGTl-9qpg3BACLcB/s1600/prize_mallorca.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="179" src="https://1.bp.blogspot.com/-LgcHEiQSZ8c/V3zUozp3udI/AAAAAAAADG0/PpgUxcn-Bxk3gGyw4DqEmrGTl-9qpg3BACLcB/s320/prize_mallorca.png" width="320" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
For now, in addition to <a href="http://steamcommunity.com/sharedfiles/filedetails/?id=698541028" target="_blank">upvoting it if you like it</a>, you can watch the trailer we prepared for Steam.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/RfNeIq4uP4Y/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/RfNeIq4uP4Y?feature=player_embedded" width="320"></iframe></div>
<div style="text-align: justify;">
<br /></div>
</div>
Anonymoushttp://www.blogger.com/profile/16393413815766208404noreply@blogger.com4tag:blogger.com,1999:blog-3999182258338242021.post-44213228554481057242016-06-13T10:17:00.003+02:002016-07-18T13:57:39.585+02:00Breaking Fast at BayDevs Retromiranda 2016<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
Hi!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
On May 21st, we presented Breaking Fast at <a href="http://www.baydevs.info/" target="_blank">BayDevs</a>, an event held within <a href="http://www.retromiranda.com/" target="_blank">Retromiranda</a> for showcasing indie games. The event was a great opportunity to gather more feedback and, even more importantly, to get to know other fantastic national indie development studios, in particular, <a href="http://www.sonsofabit.com/es/index.html" target="_blank">Sons of a Bit</a>, <a href="https://twitter.com/calcifergames" target="_blank">Calcifer Games</a> and <a href="http://morethangamers.com/landingpage2/index.php" target="_blank">MoreThanGamers</a>.<br />
<br />
The former presented its game <a href="http://www.sonsofabit.com/islabomba/es/index.html" target="_blank">Isla Bomba</a>, a puzzle platformer with lots of levels in which you have to throw bombs in the water before they explode. For this purpose, you need to combine the abilities of different animals. The game features very nice and polished 3D environments and models in the lines of the last titles of Donkey Kong, together with a fun and engaging gameplay.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
As for Calcifer Games, they presented a game called <a href="http://gamejolt.com/games/ufo-rise/60357" target="_blank">U.F.O. RISE</a>, in which you have to guide an inoffensive alien through a stage in which enemies (furious farmers) spawn continuously. The goal is to gather pieces of its broken spaceship and your only weapon is your ability to turn your enemies into allies so they can fight for you.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Finally, MoreThanGamers presented <a href="http://morethangamers.com/landingpage2/games.php" target="_blank">Crazy Princess</a>, a challenging game where you play the role of a charming prince who is pursued relentlessly by princesses who want to marry him desperately. The game starts out simple, but soon it becomes an interesting challenge because the girls are quite tough and fast.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The participating studios also had the opportunity to give a talk about their studios and their games. In the next video, you can watch part of my talk (in Spanish).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/zU6OhdoLedI/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/zU6OhdoLedI?feature=player_embedded" width="320"></iframe></div>
<br /></div>
<div style="text-align: justify;">
As for Breaking Fast, we are very happy with the feedback received from the organizers and from the attendants. In the next video, you can watch two kids enjoying the game:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/8-8yCB5j7oI/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/8-8yCB5j7oI?feature=player_embedded" width="320"></iframe></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-m0oXc61MS3I/V13IyxVBCkI/AAAAAAAADBY/_-bt5ZWdHakZoybLdQQD-XOxqmi4H7xDgCLcB/s1600/IMG_5775.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://2.bp.blogspot.com/-m0oXc61MS3I/V13IyxVBCkI/AAAAAAAADBY/_-bt5ZWdHakZoybLdQQD-XOxqmi4H7xDgCLcB/s320/IMG_5775.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-gHb_SB4K7Nc/V13IyyTdfiI/AAAAAAAADBU/7hGkXIfTbLIABfSCnctdRdUxWGizWFC_ACLcB/s1600/IMG_5778.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://1.bp.blogspot.com/-gHb_SB4K7Nc/V13IyyTdfiI/AAAAAAAADBU/7hGkXIfTbLIABfSCnctdRdUxWGizWFC_ACLcB/s320/IMG_5778.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-yObkIRMS_7A/V13KplomS2I/AAAAAAAADBo/iKspsTrA7fgmPWVW2jqDlEtT5YPp3thhwCLcB/s1600/IMG_5797.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="https://4.bp.blogspot.com/-yObkIRMS_7A/V13KplomS2I/AAAAAAAADBo/iKspsTrA7fgmPWVW2jqDlEtT5YPp3thhwCLcB/s320/IMG_5797.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div style="text-align: justify;">
Also, we were interviewed for <a href="http://iradio.ucam.edu/ruta-gamer" target="_blank">Ruta Gamer</a>, a podcast about videogames hosted by the Catholic University of Murcia. You can <a href="http://iradio.ucam.edu/programas/rgm-t3-10-160523" target="_blank">listen to us from minute 2</a>5.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Finally, we had the chance to visit Cartagena, a really beautiful town with dozens of historical monuments and ruins. That fabulous Roman theater... </div>
<div style="text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.blogger.com/video.g?token=AD6v5dx9YPSmrGUISsj6g2B-L5lI44DNL4jO7NqNQst4wwoLN0AxDTl2hRagJIpyUg92flv_TEShXqlXMKoZzthpww' class='b-hbp-video b-uploaded' frameborder='0'></iframe></div>
<div style="text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="text-align: justify;">On Sunday, the day after the event, we could even enjoy a day of beach and sun, shellfish and fried fish :).</span></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-PDqOyik4-Z8/V13ID5ud_jI/AAAAAAAADA8/G1PHCdD8L6E-jS_33SucA6P03S3JX2WngCLcB/s1600/IMG_5790.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://2.bp.blogspot.com/-PDqOyik4-Z8/V13ID5ud_jI/AAAAAAAADA8/G1PHCdD8L6E-jS_33SucA6P03S3JX2WngCLcB/s320/IMG_5790.jpg" width="232" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-OEbFHihhvHU/V13Ic11L4JI/AAAAAAAADBI/q0wJHkV5uLI46xq5vrgQ3Te44wkpPeALQCLcB/s1600/IMG_5724.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://4.bp.blogspot.com/-OEbFHihhvHU/V13Ic11L4JI/AAAAAAAADBI/q0wJHkV5uLI46xq5vrgQ3Te44wkpPeALQCLcB/s320/IMG_5724.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-5qiXpeSnEAM/V13Hut_eCiI/AAAAAAAADAo/rtrdmqwiuXkt2tNZ2a7kVVGHEUpy27dfwCLcB/s1600/IMG_5794.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://3.bp.blogspot.com/-5qiXpeSnEAM/V13Hut_eCiI/AAAAAAAADAo/rtrdmqwiuXkt2tNZ2a7kVVGHEUpy27dfwCLcB/s320/IMG_5794.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-ZklKNr7CVU8/V13H1h11SCI/AAAAAAAADA0/zfUsr-wzs2wxinQylGB-lxSP6YwRe6RSQCLcB/s1600/IMG_5792.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://3.bp.blogspot.com/-ZklKNr7CVU8/V13H1h11SCI/AAAAAAAADA0/zfUsr-wzs2wxinQylGB-lxSP6YwRe6RSQCLcB/s320/IMG_5792.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Hope you have enjoyed reading about our adventure in Cartagena. </div>
<div class="separator" style="clear: both; text-align: left;">
FM</div>
</div>
Anonymoushttp://www.blogger.com/profile/16393413815766208404noreply@blogger.com6tag:blogger.com,1999:blog-3999182258338242021.post-91811207653238794852016-05-13T10:00:00.000+02:002016-05-17T10:40:13.006+02:00A Brief PAX East 2016 Post-mortem<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
Hi folks!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
As many of you probably know, we were presenting our game Breaking Fast during PAX East 2016. It has been the first time that we have attended this event, and it has been actually the first time that we have shown Breaking Fast in any game event and in front of such a huge game audience. Without further ado, I am going to summarize our experience during PAX.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<b>Pre-PAX story</b></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Back in the end of February, we were considering whether it would be feasible to attend this event. By that time, the game was in a very raw state, but we did want to take advantage of any opportunity to promote the game, so I filled out the contact form that was available on the PAX website, 'just in case', I told to myself. Some time later, a PAX sales manager contacted us via e-mail to request more information about the game. We sent him what we had at that time: a brief description of the game, a link to our website, and a video where the game was succinctly introduced, shown below.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/_lnMWMdKXuk/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/_lnMWMdKXuk?feature=player_embedded" width="320"></iframe></div>
<br />
<div style="text-align: justify;">
Some time later, he responded that the game seemed really fun, and he encouraged us to contact him again when we had something more solid. In an outburst of optimism, we told him that we would reach out to him again in two weeks with a playable demo of the game. Of course, we understimated the effort that this goal would entail.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
After a month of intense work, by the beginning of April, we had the demo and we had recorded some new gameplay videos in which some friends were playing the game. We had lost our hope to attend PAX because the event would take place in just three weeks. Since I wanted to keep the contact with the sales manager, and also with a view to have some chance for next year, we sent him the demo and the new gameplay video. A big surprise arrived in the form of a reply to our e-mail: "Awesome! I have a 10x10 available at East for you guys if you’re still interested in exhibiting. I know the show is coming up fast.".</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
At that point, we were a bit in shock, because we really had lost all hope to attend the event, and now we had to decide quickly whether we wanted to make a sudden moderately high investment. Of course, as you may have followed our tweets and Facebook posts, you know that we took the offer.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
In two weeks, we had to make all the arrangements. Fortunately, flying to Boston is not too expensive (not at least as expensive as New York), and we found a good offer for a <a href="http://www.godfreyhotelboston.com/" target="_blank">really nice hotel</a>, which turned out to be excellent. However, we still needed to make lots of preparations for the event, including all the material that we would be taking: tee-shirts, posters, x-banner, business cards, flyers, and plenty of electronic devices that we could not afford hiring there. As you can guess, our luggage was kind of heavy... </div>
<br />
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-W2QhnRHRy8Y/VzSlyxfJXoI/AAAAAAAAC_s/K3ZRQHuBNUcNvtNwA26M0WAUU3RzIWdbgCLcB/s1600/IMG_6157.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://4.bp.blogspot.com/-W2QhnRHRy8Y/VzSlyxfJXoI/AAAAAAAAC_s/K3ZRQHuBNUcNvtNwA26M0WAUU3RzIWdbgCLcB/s320/IMG_6157.jpg" width="320" /></a></div>
<br /></div>
<div style="text-align: justify;">
As part of the registration in PAX, we received a huge list with press contacts that would attend the event. We attempted to reach as many as these contacts as we could, although we knew that it would be difficult to make appointments with such a short antipication. In fact, we only received around 8 replies to the burst of e-mails that we sent.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
And of course, and more importantly, we needed to polish the game and we wanted to add more characters. Actually, <a href="https://twitter.com/ManuelaRMontiel" target="_blank">Manuela </a>(the artist) sketched and designed the bacon during our flight connection in London, and it was the most popular among all the characters!</div>
<br />
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-tDoL_1rjoYU/VzNZP0liWZI/AAAAAAAAC-4/1ohlllqyLvUZAonipUhZ3wVXbV7Pp79oQCLcB/s1600/bacon.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://3.bp.blogspot.com/-tDoL_1rjoYU/VzNZP0liWZI/AAAAAAAAC-4/1ohlllqyLvUZAonipUhZ3wVXbV7Pp79oQCLcB/s320/bacon.png" width="317" /></a></div>
<div style="text-align: center;">
Bacon, the popular!</div>
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<b>During PAX</b></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
For those of you who have had the chance to attend PAX, you surely know that it comprises a huge expo floor. We were really amazed while admiring the stands that big companies were setting up upon our arrival. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-Mflqe5M0QgY/VzNcfG1KCII/AAAAAAAAC_I/u-JBjOm7E94KJq-9snzRGJ7Izs_q4ZiHACLcB/s1600/IMG_5339.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://1.bp.blogspot.com/-Mflqe5M0QgY/VzNcfG1KCII/AAAAAAAAC_I/u-JBjOm7E94KJq-9snzRGJ7Izs_q4ZiHACLcB/s320/IMG_5339.JPG" width="320" /></a></div>
<div style="text-align: center;">
<a href="http://store.steampowered.com/app/407530/" target="_blank">Survival of the Fittest</a> featured an awesom T-rex that people could ride for a nice picture. </div>
<div style="text-align: center;">
When there is budget...</div>
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The set-up of the booth was smooth, except for an unfortunate setback: we had taken three PC screens with the idea of using one of them for looping a teaser of the game, and the other two for playing. However, one of the PC screens had apparently suffered a stroke during the flight and was broken. I was a bit irritated, but fortunately, we realized this on Thursday evening, not too late, and we had some time to buy a new one, which was cheaper than it is here in Spain, and which was better; every cloud has a silver lining.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/FpQaLJCXN50/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/FpQaLJCXN50?feature=player_embedded" width="320"></iframe></div>
</div>
<div style="text-align: justify;">
<div style="text-align: center;">
<br />
Breaking Fast Teaser</div>
<br /></div>
<div style="text-align: justify;">
Our general experience during PAX was great, with lots of people willing to play our game and to rate it as "very fun" or "addictive". Some of them were certain that the game would be a hit and were disappointed to know that the game was not available yet. We collected as many e-mails of potentially interested buyers as we could.<br />
<br />
There is an important issue that we overlooked at first but that we fortunately corrected soon: the booth distribution. On the first day, Friday, the booth was organized with the table perpendicular to the surface, as you can see below.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-0HjDFmnJumI/VzR6HxIx9EI/AAAAAAAAC_Y/7TfCtStHK-ESkoq_ONWgDoVB6_WrK1C6QCLcB/s1600/IMG_5357.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://1.bp.blogspot.com/-0HjDFmnJumI/VzR6HxIx9EI/AAAAAAAAC_Y/7TfCtStHK-ESkoq_ONWgDoVB6_WrK1C6QCLcB/s320/IMG_5357.JPG" width="320" /></a></div>
<div style="text-align: center;">
Original booth distribution</div>
<br />
This seemingly normal distribution turned out to be a psychological barrier for many people who were curious about the game but were reluctant to "come into" the booth to try it. Changing the distribution in such a way that the game was available to any passer-by made a big impact: even when on Friday lots of people played the game, on Saturday and Sunday (days on which we had already changed the distribution) there were peak moments with people linining up to play and watching how others played. This was an important lesson for us: <b>make as easy as possible for players to play your game</b>; don't assume that people who want to play the game will actually do it if they have to engage in a close relationship or a conversation.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-qqzWIWbTNO8/VzR6LySOFYI/AAAAAAAAC_c/WLY8I5pZNfg2Gh6LVdKTFY1MKww5hH_qgCLcB/s1600/IMG_5402.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://1.bp.blogspot.com/-qqzWIWbTNO8/VzR6LySOFYI/AAAAAAAAC_c/WLY8I5pZNfg2Gh6LVdKTFY1MKww5hH_qgCLcB/s320/IMG_5402.JPG" width="320" /></a></div>
<div style="text-align: center;">
Changed distribution: passers-by could play directly the game without entering the booth</div>
<br />
As a final note to my PAX experience, I want to boast about something: I could introduce myself and talk a little bit with Ron Gilbert, the creator of a masterpiece known as <a href="https://en.wikipedia.org/wiki/Monkey_Island_%28series%29" target="_blank">Monkey Island</a>. He was there presenting his own game called <a href="https://blog.thimbleweedpark.com/" target="_blank">Thimbleweed Park</a>, which is really promising, especially for those lovers of old-school adventure games.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<b>Post-PAX, now what?</b></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Watching hundreds of people playing your game provides an invaluable feedback and you get a good sense of what people like the most and the least. We intend to release the game by the end of summer, and therefore we still have time to improve over the weaker points of the game and to polish the stronger ones.<br />
<br />
There are other events coming up and we plan to present the game there; these events include <a href="http://www.retromiranda.com/category/indie/" target="_blank">Retromiranda Baydevs</a>, <a href="http://www.mallorcagame.es/" target="_blank">Mallorca Game</a>, and <a href="http://www.gamepolis.org/web/" target="_blank">Gamepolis</a>, although we do not discard attending other international events. In the end, we are just seeking the biggest possible feedback as well as to raise awareness of the game so that potentially interested people learn about it before the release.<br />
<br />
If you have any specific question about our experience in PAX, do not hesitate to leave a comment.<br />
<br />
Thanks for reading and see you!<br />
FM</div>
</div>
Anonymoushttp://www.blogger.com/profile/16393413815766208404noreply@blogger.com8tag:blogger.com,1999:blog-3999182258338242021.post-64878339461547777852016-04-04T09:31:00.000+02:002016-04-04T09:31:09.219+02:00The Importance of Early Feedback and Testing<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
Hi all!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
How are you doing? We continue working hard on Breaking Fast to make it the best game you've ever played in you life! ... </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Last week we had a couple of testing sessions with people external to the development team, and these sessions were quite eye-opening in two senses: first, it allowed us discovering some bugs, which is the tradional goal of testing; but second and more importantly, we noticed that some design aspects were misleading, and others that we didn't consider so important were actually key to the players.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
In this post, I intend to emphasize the importance of this early feedback and to summarize the most important changes that we applied as a result of this feedback. You may think that some of the changes are subtle, but sometimes a subtle change may cause a major impact on the overall gaming experience. You may also think that some changes were <i>obviously </i>required, but here's the key to external feedback: once you're very focused on your project, it's easy to lose pespective and you need someone to shove you back so that you can see the complete image instead of the individual pixel.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Why is early feedback that important? In addition to the <i>loss of perspective</i> reason, obtaining feedback may help you not diverting too much from your original goal. Usually, people ask you what your game is about, and you can compare your answer with the impressions that people get when they play your game. If you see they don't match, you can take actions quickly.<br />
<br />
Also, it is a well-known principle for software engineers that the difficulty in performing changes on software increases as the development moves forward. This is known as the <a href="http://paulhammant.com/2012/11/01/testability-and-cost-of-change/" target="_blank">cost curve, first proposed by Boehm</a>. Therefore, early feedback may result in cheaper development changes.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-az6qwzxu1Go/VwFEfmeez6I/AAAAAAAAC9o/oaA4h67r95U_zaTfovM70ssVazgWY4VNQ/s1600/BoehmCurve.GIF" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://3.bp.blogspot.com/-az6qwzxu1Go/VwFEfmeez6I/AAAAAAAAC9o/oaA4h67r95U_zaTfovM70ssVazgWY4VNQ/s1600/BoehmCurve.GIF" /></a></div>
<div style="text-align: center;">
Figure 1. Boehm's Curve (from <a href="http://www.agile-process.org/change.html" target="_blank">http://www.agile-process.org/change.html</a>)</div>
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
And how did we change Breaking Fast as a result of the early feedback? Here we go with a summary of the most relevant changes:</div>
<div style="text-align: justify;">
<ol>
<li>Position must be always visible: at first, we decided that showing the distance covered by each player was enough. However, thanks to the feedback, it became clear that players expect to see their positions continously. Therefore, we added an element in the HUD to show this information. Still, we need to sort out how to show the relative position with each other player and the distance among players. But now we are sure that this is a problem that is worth the effort.</li>
<li>Throwing stuff is cool: in Breaking Fast, there are two types of boosters; those that activate an attack as soon as they are picked, and others that require the players to throw something explicitly. In our testing session we understood that players felt more rewarded when they could throw somehting they had picked. Therefore, a booster that originally was designed to be activated automatically was re-designed to be thrown.</li>
<li>Physical attacks must stand out: characters in Breaking Fast can attack each other physically. This is a cool and fun mechanic, but players of the testing session agreed that the animations should stand out more, especially because characters in 3 players or 4 players races are small. So we decided to exagerate the animation.</li>
<li>Players want to know that the race is ending: in several races there were a couple of players that didn't realize that the race had ended and felt frustrated because they could not control the character anymore. We have solved this by a) adding an alarm that is triggered when there are 10 seconds remaining; b) by showing these 10 seconds bigger on the screen; c) and by accompanying each of the last 10 seconds with an audible tick sound.</li>
<li>Beginning of the race: we designed the beginning of the race in such a way that players had to press the movement key/button only when the initial countdown had gone to zero; otherwise, characters wouldn't move until they pressed the buttons again. This initial idea was implemented in order to require more precision from the players, but it turned out to give the impression that their controls didn't work, and it wasn't that fun anyway, so we discarded it.</li>
<li>Turbo was a big advantage: characters in Breaking Fast can activate their turbo upon some conditions. However, the original design made the turbo too advantageous for those meeting those conditions and mastering the controls. We therefore redesigned this mechanic to make it harder to exploit.</li>
<li>Bugs detection: of course, we found some bugs that fortunately could be quickly fixed, but we wouldn't have been aware of them hadn't been for the testing session with several players doing lots of stuff concurrently.</li>
</ol>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-waGw9e2qmC8/VwIYCoTzCiI/AAAAAAAAC94/eWgjrx37-Homr0mODeCrJlOEgC_qhEA8A/s1600/Breaking%2BFast%2B01_04_2016%2B10_53_09.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="225" src="https://3.bp.blogspot.com/-waGw9e2qmC8/VwIYCoTzCiI/AAAAAAAAC94/eWgjrx37-Homr0mODeCrJlOEgC_qhEA8A/s400/Breaking%2BFast%2B01_04_2016%2B10_53_09.png" width="400" /></a></div>
</div>
<div style="text-align: justify;">
And this is it! I hope you're more conviced (if you weren't) to test your game and to retrieve early feedback as soon as possible. In the end, it's in your best interest and will save you development time.<br />
<br />
See you!<br />
FM</div>
</div>
Anonymoushttp://www.blogger.com/profile/16393413815766208404noreply@blogger.com0tag:blogger.com,1999:blog-3999182258338242021.post-75509457192051990242016-03-13T11:38:00.002+01:002016-03-13T11:38:31.262+01:00Progress of Breaking Fast: Boosters, Animations and Collectables<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
Hi buddies!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
How are you doing? We continue working hard and happy on Breaking Fast. Our goal is to have a playable level for the next week. In this post, I summarize the most important advances that have been accomplished since the last post:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
- <b>New boosters</b>: we are always thinking of new ways for players to mess up with their adversaries. We have a very interesting new booster in this direction, but we don't want to spoil it yet. More information very soon!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
- <b>Collectables</b>: when we first conceived Breaking Fast, collectables (i.e. items that players can collect during the race) were not considered. However, after thinking more about it and prototyping a bit, we have changed our minds: collectables can add more depth to the gameplay. These collectables now fill the players' enery bars, with which they can run faster for a period of time. Although we don't have the final art for the collectables, we have their tracking behaviour, as you can watch in the following video: </div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.blogger.com/video.g?token=AD6v5dziSyZFflFZiSJ1JBms1lZoufl6q-eHFIZ6W4TNMs4qP2oRUjhTHFJuWFFp-414mRW9RKnsMi82-rC1OSss7g' class='b-hbp-video b-uploaded' frameborder='0'></iframe></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
- <b>Animations integration</b>: we added animations for the toasters, the beaters and the player. The following videos show the first two:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.blogger.com/video.g?token=AD6v5dymjX2LhbNZoaBddVgsUCvwR5ef6ba_uIDQwbhDdVNFZjiWhMtgkbtsUq5FsjXbwFlliiJvECesO_-M1FxDsA' class='b-hbp-video b-uploaded' frameborder='0'></iframe> </div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.blogger.com/video.g?token=AD6v5dwb4QxHVeITVrBXdCnpBKxyverBN1d3Uj8up8J81MGL8EhDrFu67qBgNJgbLvXy8TTEWHeoWVbJR0YBHYIzDA' class='b-hbp-video b-uploaded' frameborder='0'></iframe></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div style="text-align: justify;">
- <b>Refactoring of code for player management</b>: this is not something observable, but it took quite a while and has helped me better understand how to modify the behaviour of players. Before the refactoring, the code for player management was a bit tangled and therefore, adding any new feature to their movements or perform any modification to their behaviours were tasks that really gave me the creeps. To put it simple, the refactoring consists of identifying different and exclusive states (e.g. jumping and rolling) and perform the updates of each state in different functions. That way, I don't need lots of variables to manage the mutable state, but I can make do with a single instance variable that holds the current state.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
- <b>Leap against obstacles</b>: the player can now jump against obstacles to reach new places. This is something that would have been very tedious to add and prone to error, hadn't been for the aforementioned refactoring.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
More videos with the new features and effects will be available soon on our <a href="https://www.youtube.com/channel/UC2tNqogjRS2d6ZyCWz1UkRw" target="_blank">Youtube channel</a> and the rest of the social networks You can find more information to keep in contact on our <a href="http://www.talestudios.com/" target="_blank">web page</a>, where you can also subscribe to receive the latest news on the advances of Breaking Fast.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
FM</div>
</div>
Anonymoushttp://www.blogger.com/profile/16393413815766208404noreply@blogger.com1tag:blogger.com,1999:blog-3999182258338242021.post-32065525764515863242016-02-29T10:00:00.000+01:002016-02-29T10:00:13.122+01:00Breaking Fast: Menu Navigation<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
Hi all!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Breaking Fast is moving forward. This last week we worked on the menu navigation part, which includes the menu screens through which players navigate until the race begins. As for the technical side, I want to discuss the two main issues you have to consider when implementing this aspect of a game: how to manage the flow between screens, and how to pass information among screens. Let's get started!</div>
<div style="text-align: justify;">
<br />
<b>Flow Management Schemes</b><br />
<br /></div>
<div style="text-align: justify;">
There are two main "schemes" (I can't think of a better word) during menu navigation. In the first scheme, each screen is actually a different screen. This implies that, upon changing among screens, we swap the contents of one screen with the contents of the other screen. This can be implemented as a function in the screen manager:</div>
<br />
<pre style="background: #f0f0f0; border: 1px dashed #cccccc; color: black; font-family: "arial"; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> function changeScreen(newScreen)
currentScreen.unload()
currentScreen = newScreen
currentScreen.load()
end
</code></pre>
<br />
<div style="text-align: justify;">
In order to manage transitions among screens (i.e. the implementation of the screen manager), it is useful to think of Finite State Machines. You can watch a series of two videos that I prepared for gaining insight on the matter.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/chQ2tgB_mFY/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/chQ2tgB_mFY?feature=player_embedded" width="320"></iframe></div>
<br />
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/IXYntNv62K0/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/IXYntNv62K0?feature=player_embedded" width="320"></iframe></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
In games it is also very common to use another scheme, in which the contents of different screens are all drawn, but only one of them has the focus at any moment. Think for example of a racing game in which you have to choose a scenario and then, the time of the race. You can implement this by using the aforementioned scheme, but it feels kind of overkill to unload one screen and to load another one just for the purpose of selecting the time. It seems more natural that the same screen presents both options, but that the player can only change one of them at any time. Actually, we can stop thinking of different screens in this situation. This "move the focus" approach can be implemented by means of screen phases or <i>states</i>. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
In particular, in Lua, we can hold a table of states, and we iterate over this table in order to draw and update the screen. We also have a variable that holds the value of the current state (the current focus), and we delegate the interaction of the player (be it with the keyboard or a gamepad) to the actual focused state. Some self-explanatory code is shown next:</div>
<br />
<pre style="background: #f0f0f0; border: 1px dashed #cccccc; color: black; font-family: "arial"; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> function load()
table.insert(states, state1)
table.insert(states, state2)
currentStateFocus = state1
end
function draw()
for _, v in ipairs(states) do
v.draw()
end
end
function update(dt)
for _, v in ipairs(states) do
v.update(dt)
end
end
function onKeyPressed(key)
currentStateFocus.onKeyPressed(key)
end
</code></pre>
<br />
<b>Communication between Screens and States</b><br />
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Passing information among screens is essential. In particular for Breaking Fast, consider the following flow of actions: </div>
<ol style="text-align: left;">
<li>Players select the characters that will participate in the race.</li>
<li>Players select the scenario in which the race will take place.</li>
<li>Players select the duration of the race.</li>
</ol>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-pPFv_JEIUW4/VtGffQNC7hI/AAAAAAAAC80/cilSY9PQ-aM/s1600/Imagen1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="125" src="https://3.bp.blogspot.com/-pPFv_JEIUW4/VtGffQNC7hI/AAAAAAAAC80/cilSY9PQ-aM/s400/Imagen1.png" width="400" /></a></div>
<div style="text-align: justify;">
Consider the figure above, in which we mix the two menu navigation schemes explained before. Each transition among screens and states conveys both new information and the information carried by older transitions. In the end, when we prepare the race screen, we need to know all the options that have been chosen by the players through the different screens. Fortunately, implementing this in Lua is very simple thanks to a powerful feature of the language: function overriding of imported modules. Consider the following module, which models the Time Selection State:</div>
<div style="text-align: justify;">
<br /></div>
<pre style="background: #f0f0f0; border: 1px dashed #cccccc; color: black; font-family: "arial"; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> local timeSelectionState = {}
-- other functions
function timeSelectionState.toScenarioSelection()
end
function timeSelectionState.toGame(timeChosen)
end
return timeSelectionState
</code></pre>
<br />
<div style="text-align: justify;">
As you can see, we are defining two empty functions. Any module that imports this module can re-define (i.e. override) these functions. So for example, consider the Scenario Selection Screen module, which contains the Time Selection State:</div>
<br />
<pre style="background: #f0f0f0; border: 1px dashed #cccccc; color: black; font-family: "arial"; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> local scenarioSelectionScreen = {}
-- other functions
function timeSelectionState.toScenarioSelection()
currentStateFocus = scenarioSelectionState
end
function timeSelectionState.toGame(timeChosen)
for _, v in ipairs(states) do
v.unloadResources()
end
scenarioSelectionScreen.toGame(numberOfPlayers, playersInfo, scenarioChosen, timeChosen)
end
function scenarioSelectionScreen.toGame(numberOfPlayers, playersInfo, scenarioChosen, timeChosen)
end
return scenarioSelectionScreen
</code></pre>
<br />
<div style="text-align: justify;">
As you can observe, this module re-defines <i>toScenarioSelction()</i> and <i>toGame()</i> functions. In particular, <i>toGame()</i> unloads all the states of this screen, forwards the racing time that has been chosen by the player, and pads it to more information accumulated during previous phases. In turn, <i>scenarioSelectionScreen</i> defines an empty <i>toGame()</i> function that cam be re-defined by the module importing it. This latter module could therefore add some more information and pass it to the Race Screen.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
And this is it! As always, I hope you enjoyed this tutorial, and if you have any question, don't hesitate to ask! Any feedback is also well appreciated.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
See you!</div>
<div style="text-align: justify;">
FM</div>
</div>
Anonymoushttp://www.blogger.com/profile/16393413815766208404noreply@blogger.com36tag:blogger.com,1999:blog-3999182258338242021.post-31879973951540219092016-02-21T12:06:00.002+01:002016-02-21T12:06:52.026+01:00Breaking Fast: From Ad-Hoc to Scalable Local Multiplayer System<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
Hi!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This week we have been working on the local multiplayer of Breaking Fast. The first version of Breaking Fast, which was playtested several months ago, had an ad-hoc art design for only two players, and therefore neither the art nor the code were scalable for moving easily from 1 to 4 players. Therefore, the main work carried out during this week has consisted of refactoring the code so that it accepts a unique set of assets, and that it scales this set according to the number of players. Also, different viewports are created according to the number of players, as shown later.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
As every programmer that is reading this post can figure, even for a medium-sized codebase the aformentioned task entails lots of work, but going step by step is the only way to go. In the following sections, I briefly explain the most important code changes that were performed:<br />
<br />
<div style="text-align: justify;">
<b>1) Substituting scalar values by arrays of values</b>: in the first version of the post, we had something like:</div>
</div>
<div style="text-align: justify;">
<br /></div>
<pre style="background: #f0f0f0; border: 1px dashed #cccccc; color: black; font-family: "arial"; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> local Camera = require "Camera"
local camera1 = Camera()
local camera2 = Camera()
local Player = require "Player"
local player1 = Player.new(...)
local player2 = Player.new(...)
</code></pre>
<div style="text-align: justify;">
<br />
Of course, if we want to achieve scalability, this is not the way to go. Therefore, we changed the aforementioned scalar variables into arrays, as follows:<br />
<br />
<pre style="background: #f0f0f0; border: 1px dashed #cccccc; color: black; font-family: "arial"; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> local Camera = require "Camera"
for i = 1, numPlayers do
cameras[i] = Camera()
end
local Player = require "Player"
for i = 1, numPlayers do
players[i] = Player.new(...)
end
</code></pre>
<br />
This applies of course to every element that needs to be replicated according to the number of players.<br />
<br />
<b>2) Re-designing assets for one player scenario: </b>in the single player mode, there are no viewports (there are no any other player), and therefore the assets need to be as large as they can be. Under any other circumstances (more than one player), the assets need to be scaled down proportionally according to the resolution and aspect ratio for which the game is being developed, 1920x1080 and 16:9, respectively.<br />
<br />
In the first prototype of the game, the assets were designed ad-hoc for two players. For example, the background was designed with a resolution of 1920 x 540, and I would place two different backgrounds in different positions:<br />
<br />
<pre style="background: #f0f0f0; border: 1px dashed #cccccc; color: black; font-family: "arial"; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> background1 = love.graphics.newImage("background.png")
love.graphics.draw(background1, 0, 0)
background2 = love.graphics.newImage("background.png")
love.graphics.draw(background2, 0, 540)
</code></pre>
<br />
<i>(This is an oversimplification for several reasons; first, we actually add the background to a layer of a camera, because we want it to scroll a little bit. Read <a href="http://becomingindiedev.blogspot.com.es/2015/11/parallax-scrolling-in-love2d-part-1.html" target="_blank">this series of posts</a> to get more information on parallax scrolling. Also, what we actually draw is not the background itself, but a batch of backgrounds that we paste once after another in order minimize draw calls and provide an illusion of infinite scenario).</i><br />
<br />
After the changes, we have only one background with a resolution of 1920 x 1080*, and therefore we don't need to place background for different players in different positions; the viewports will take care of this according to the number of players.<br />
<br />
<i>*(Again, although this would be technically possible, we use a larger resolution to support scrolling in the vertical axis and for fixing some problems with different aspect ratios, as discussed later).</i><br />
<br />
<b>3) Designing viewports: </b>if we want that more than one player can play on the same machine, we need to provide each player with a fragment of the screen. Each fragment is called a viewport. In the first prototype, we didn't need to worry about viewports, because everything was drawn ad-hoc for two players. However, now we have a unique set of assets, and depending on the number of players, these assets must be replicated for the different players and must be scaled down appropriately.<br />
<br />
For example, for two players, we want that the first player is allocated the upper half of the screen, whereas the second player should be provided with the lower half. In the case of four players, each player should have a quarter of the screen. <br />
<br />
In order to implement viewports in <a href="https://love2d.org/" target="_blank">Löve</a>, I saw two alternatives: using <a href="https://love2d.org/wiki/love.graphics.setScissor" target="_blank">sciss<span id="goog_869091198"></span><span id="goog_869091199"></span>ors</a> or <a href="https://love2d.org/wiki/Canvas" target="_blank">canvases</a>. I didn't get to really grasp how to use scissors for this purpose in my first attempts (see video below), so I switched my attention quickly to the second option, which turned out to work great.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.blogger.com/video.g?token=AD6v5dyz7pz0Hs0x5v7sSduJibu9g2lvsYRTOzaPwMz-HjH2k18nV43d2tODpTtfuUSx48F2tGpngsAShrPzWsIs6g' class='b-hbp-video b-uploaded' frameborder='0'></iframe></div>
<br />
<div style="text-align: center;">
Fail with using scissor. The second player viewport was rendered onto the first player one.</div>
<br />
Canvases represent an off-screen rendering target. Internally, it creates an OpenGL framebuffer object to which the contents are drawn, instead of drawing the contents to the screen. The process from a high-level perspective is as follows:<br />
<ol>
<li>Create as many canvases as the number of players (one canvas per camera).</li>
<li>Depending on the number of players, scale the assets that will be drawn to the canvases.</li>
<li>Place each canvas in its correct position according to the number of players.</li>
<li>Draw all the stuff that we used to draw on the screen on the canvases instead, and then, draw the the canvases.</li>
</ol>
Some simplified code for the three players case is shown next:<br />
<br />
<pre style="background: #f0f0f0; border: 1px dashed #cccccc; color: black; font-family: "arial"; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> if numPlayers == 3 then
cameras[1]:setScale(2, 2)
cameras[1]:createCanvas(0.5 * intendedWidth, 0.5 * intentedHeight, 0, 0)
cameras[2]:setScale(2, 2)
cameras[2]:createCanvas(0.5 * intendedWidth, 0.5 * intentedHeight, 0.5 * intendedWidth, 0)
cameras[3]:setScale(2, 2)
cameras[3]:createCanvas(0.5 * intendedWidth, 0.5 * intentedHeight, 0.25 * intendedWidth, 0.5 * intentedHeight)
...
</code></pre>
<br />
The <i>createCanvas()</i> function, which is added to my camera module, takes the width and height of the canvas, and its top left position. This would yield the following layout for the screen: <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-7aX-AyWGIuU/VshZpMAXRqI/AAAAAAAAC7Y/oyZJHyLOubg/s1600/Imagen1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="179" src="https://1.bp.blogspot.com/-7aX-AyWGIuU/VshZpMAXRqI/AAAAAAAAC7Y/oyZJHyLOubg/s320/Imagen1.png" width="320" /></a></div>
<br />
As part of this viewport design, we also needed to change the camera code for drawing. However, modifying this code to support drawing on canvases was surprisingly easy.<br />
<br />
<i>camera.lua</i><br />
<br />
<pre style="background: #f0f0f0; border: 1px dashed #cccccc; color: black; font-family: "arial"; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> function camera:draw()
<b> love.graphics.setCanvas(self.canvas)
love.graphics.clear() </b>
local bx, by = self.x, self.y
for _, v in ipairs(self.layers) do
self.x = bx * v.scale
self.y = by * v.scale
self:set()
v.draw()
self:unset()
end
self.x, self.y = bx, by
<b> love.graphics.setCanvas()
love.graphics.draw(self.canvas, self.canvasLeft, self.canvasTop) </b>
end
</code></pre>
<br />
The lines in bold text are the only additions we needed to add in order to make the function work with canvases.<br />
<br />
You can watch the result of our work in the following video. <i><b>Challenge 1: By the way, do you recognize the musical masterpiece that goes with the video? </b></i>:P<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.blogger.com/video.g?token=AD6v5dxUpR6xh9BH84rg7UVbxKGGOnSV8ihXPY5-QPoY2oWQbkV48sIJFIdd7vUutzvVtDf_msIHLPTIUP6RbHfKfA' class='b-hbp-video b-uploaded' frameborder='0'></iframe></div>
<br />
<b>4) Managing aspect ratios</b>: ensuring that Breaking Fast can be played on most aspect ratios is vital, but it is also tricky. The solution requires twofold work from the artistic and code perspectives.<br />
<br />
First, let's see what happens when we execute the code for two players for a 16:9 aspect ratio (the aspect ratio for which the game is being developed):<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-U_79RDqKGvM/VsmSHX9hOyI/AAAAAAAAC7o/kUKlCDP3IHE/s1600/Captura.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="https://4.bp.blogspot.com/-U_79RDqKGvM/VsmSHX9hOyI/AAAAAAAAC7o/kUKlCDP3IHE/s320/Captura.PNG" width="320" /></a></div>
<br />
Now, consider the same code but for a resolution of 1280 x 800, which is a 16:10 aspect ratio and very common for a Macbook Pro, for example:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-kunCXliBfsk/VsmTsflFRZI/AAAAAAAAC78/QSQka1fpvv4/s1600/Captura2.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="199" src="https://3.bp.blogspot.com/-kunCXliBfsk/VsmTsflFRZI/AAAAAAAAC78/QSQka1fpvv4/s320/Captura2.PNG" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-zC8s2MVeuKM/VsmSvNyrdmI/AAAAAAAAC7s/bZrFCkMg4B4/s1600/Captura2.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><br /></a></div>
As you can see, the assets within the canvases are not properly scaled. Well, actually, they are properly adjusted to the width (note that the countdown on the top right corner is properly placed), but not to the height, because some part of the scenario is lost, like the legs of the characteres.<br />
<br />
In order to solve this, the trick is to scale all the assets down to adjust them to the height of the screen, and given that the assets (e.g. the background) are bigger than the screen, the player will have the impression that the adjustement has been perfectly done in both dimensions, as shown next:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-qhEyNf7taOk/VsmU1OZ_twI/AAAAAAAAC8I/ynOm1SF7Ccg/s1600/Captura3.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="201" src="https://4.bp.blogspot.com/-qhEyNf7taOk/VsmU1OZ_twI/AAAAAAAAC8I/ynOm1SF7Ccg/s320/Captura3.PNG" width="320" /></a></div>
<br />
There is only one inconvenience. As we are losing the perfect adjustment to the width, the HUD elements like the energy bar or the countdown are not perfectly in the middle or at the end of the screen, respectively, but they have a small offset to the left.<br />
<br />
Assuming that we have a perfect adjustment to the width, the middle of the screen is calculated as:<br />
<br />
<i>screenMiddleX = 0.5 * intendedWidth</i><br />
<br />
, where intendedWidth is the width of the design resolution (1920). If we want to correct the position, we need to multiply this value by the following proportion:<br />
<br />
<i>screenMiddleX = 0.5 * intendedWidth * (scaleForAdjustToHeight / scaleForAdjustToWidth)</i><br />
<br />
The result would be as follows:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-jkGlVDGkcBg/VsmXifiKGfI/AAAAAAAAC8U/Mn-reIc4MQM/s1600/Captura4.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="199" src="https://4.bp.blogspot.com/-jkGlVDGkcBg/VsmXifiKGfI/AAAAAAAAC8U/Mn-reIc4MQM/s320/Captura4.PNG" width="320" /></a></div>
<br />
Note that now the HUD elements are now properly placed. The result for many different aspect ratios is shown in the next video. <b><i>Challenge 2: again, do you recognize the composition that accompanies the video?</i></b><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.blogger.com/video.g?token=AD6v5dwBVkYdXww6QVZZ_qRZNlIFb2mgvGzn9JDgRevvmBkIybidyVwyVDnODaIY5WP-5T4x6YBoVS07mJJEATMiJw' class='b-hbp-video b-uploaded' frameborder='0'></iframe></div>
<br />
And that's all for now. We'll keep you posted on the advances of Breaking Fast, so stay tuned!<br />
<br />
See you!<br />
FM</div>
</div>
Anonymoushttp://www.blogger.com/profile/16393413815766208404noreply@blogger.com1tag:blogger.com,1999:blog-3999182258338242021.post-87559685047763279852016-01-15T11:44:00.002+01:002016-01-15T11:44:21.229+01:00Iterator Invalidation in C++11/14 on Vector Erasure<div dir="ltr" style="text-align: left;" trbidi="on">
Hi buddies!<br />
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
How are you doing? I recently started working on another game for mobile platforms, in parallel with Breaking Fast. More news on that very soon, but today I want to share with you a problem that I found while working on a piece of code for that game.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
At some point, I wanted to test whether I should remove a laser beam from a vector of laser beams. The context was something similar to the following:</div>
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> for (auto itLasers = mPlayerLasers.begin(); itLasers != mPlayerLasers.end(); ++itLasers)
{
for (auto itEnemies = mEnemies.begin(); itEnemies != mEnemies.end(); )
{
if (collide(*itLasers, *itEnemies))
{
itEnemies = mEnemies.erase(itEnemies);
} else
{
++itEnemies;
}
} //end nested for
} //end outer for
</code></pre>
<br />
<div style="text-align: justify;">
So basically, I tested every possible laser object against every possible enemy object. If a collision is detected, then I remove the enemy from the vector of enemies.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
But wait: I have to remove the laser object that collided with the enemy as well. Assuming that a laser object can hit more than one enemy at a time (which is the behavior I want to implement), I cannot destroy the laser object until I'm done with iterating through all the enemies.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The proper solution is to have a boolean value that is set to false before entering the nested loop, and to set it to true when a collision is detected. Upon exiting the nested loop, we check this variable and update the next iterator accordingly (in the same way I update the <i>itEnemies</i> iterator). This results in the following code:</div>
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> for (auto itLasers = mPlayerLasers.begin(); itLasers != mPlayerLasers.end(); )
{
bool collision = false;
for (auto itEnemies = mEnemies.begin(); itEnemies != mEnemies.end(); )
{
if (collide(*itLasers, *itEnemies))
{
collision = true;
itEnemies = mEnemies.erase(itEnemies);
} else
{
++itEnemies;
}
} //end nested for
if (collision)
{
itLasers = mPlayerLasers.erase(itLasers);
} else
{
++itLasers;
}
} //end outer for
</code></pre>
<br />
<div style="text-align: justify;">
However, the first solution that I implemented was different, and led me to discover an error with iterators handling. This solution consisted of pushing the iterators of those lasers that collided in another vector. Then, after the loop, I would remove the elements of the vector. This is easier shown in code than explained:</div>
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> std::vector<std::vector<std::unique_ptr<LaserInfo>>::iterator> toDelete;
for (auto itLasers = mPlayerLasers.begin(); itLasers != mPlayerLasers.end(); ++itLasers)
{
for (auto itEnemies = mEnemies.begin(); itEnemies != mEnemies.end(); )
{
if (collide(*itLasers, *itEnemies))
{
//Check that it's not already in the vector
if (std::find(toDelete.begin(), toDelete.end(), itLasers) == toDelete.end())
{
toDelete.push_back(itLasers);
}
itEnemies = mEnemies.erase(itEnemies);
} else
{
++itEnemies;
}
} //end nested for
} //end outer for
for (auto it : toDelete)
{
mPlayerLasers.erase(it);
}
</code></pre>
<br />
<div style="text-align: justify;">
However, and this is the point of this post, this is completely wrong! Why? Because, according to the C++ standard in relation to the <a href="http://www.cplusplus.com/reference/vector/vector/erase/" target="_blank">erase method</a>:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<i><span style="background-color: white; font-family: verdana, arial, helvetica, sans-serif; font-size: 12px;">Iterators, pointers and references pointing to </span><span style="font-family: verdana, arial, helvetica, sans-serif; font-size: 12px;">position</span><span style="background-color: white; font-family: verdana, arial, helvetica, sans-serif; font-size: 12px;"> (or </span><span style="font-family: verdana, arial, helvetica, sans-serif; font-size: 12px;">first</span><span style="background-color: white; font-family: verdana, arial, helvetica, sans-serif; font-size: 12px;">) and beyond are invalidated, with all iterators, pointers and references to elements before </span><span style="font-family: verdana, arial, helvetica, sans-serif; font-size: 12px;">position</span><span style="background-color: white; font-family: verdana, arial, helvetica, sans-serif; font-size: 12px;"> (or </span><span style="font-family: verdana, arial, helvetica, sans-serif; font-size: 12px;">first</span><span style="background-color: white; font-family: verdana, arial, helvetica, sans-serif; font-size: 12px;">) are guaranteed to keep referring to the same elements they were referring to before the call.</span></i></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This implies that when we call erase on <i>it</i> in the second loop, all subsequent iterators are invalidated and cannot be used to erase the rest of elements. f<br />
<br />
But what happens if for some reason, we really need to defer the erasure of the laser elements? We can do it with a traditional index, as the following code illustrates: </div>
<div>
<br /></div>
<div>
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> std::vector<int> toDelete;
int index = 0;
for (auto itLasers = mPlayerLasers.begin(); itLasers != mPlayerLasers.end(); ++itLasers)
{
for (auto itEnemies = mEnemies.begin(); itEnemies != mEnemies.end(); )
{
if (collide(*itLasers, *itEnemies))
{
if (std::find(toDelete.begin(), toDelete.end(), index) == toDelete.end())
{
toDelete.push_back(index);
}
itEnemies = mEnemies.erase(itEnemies);
} else
{
++itEnemies;
}
} //end nested for
++index;
} //end outer for
int count = 0;
for (auto i : toDelete)
{
mPlayerLasers.erase(mPlayerLasers.begin() + i - count);
++count;
}
</code></pre>
<div style="text-align: justify;">
<br /></div>
<div>
<div style="text-align: justify;">
Now, we are storing the index of the laser to be removed in the <i>toDelete</i> vector. Then, during the second loop, we access the elements through the index. We need to consider all the elements that have been erased at each execution of the loop by using the <i>count</i> variable, because <i>erase()</i> relocates all the elements that go after the removed element, moving them one position to the left.<br />
<br />
And that's all. See you soon!<br />
FM </div>
</div>
<div>
<br /></div>
</div>
</div>
Anonymoushttp://www.blogger.com/profile/16393413815766208404noreply@blogger.com1tag:blogger.com,1999:blog-3999182258338242021.post-27371222286752646372015-12-29T10:00:00.000+01:002015-12-29T14:36:21.357+01:00Parallax Scrolling in Love2d. Part 3: Different Camera Spaces<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
Hi!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This is the last installment of the series on parallax scrolling in Love2d. In the previous posts, we first discussed how we could implement this technique by <a href="http://becomingindiedev.blogspot.com.es/2015/11/parallax-scrolling-in-love2d-part-1.html" target="_blank">defining a camera component</a> and the concept of layers, and how we could <a href="http://becomingindiedev.blogspot.com.es/2015/12/parallax-scrolling-in-love2d-part-2.html" target="_blank">reason about the two different coordinate</a> systems that we had: the world and the camera coordinate systems. Consider reading these previous posts before going on, because this installment builds upon them. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
We will see now how we can represent an object that is in a given camera space in another camera space, which can be useful for multiplayer games. The problem statement is depicted in Figure 1. We see that we have two cameras, each one representing a fragment of the same world. One of the cameras (camera 1) is in the position (x1, y1), whereas camera 2 is in (x2, y2). Again, for the sake of simplicity, we will focus on the X dimension, but the same reasoning applies to the Y dimension. Each camera follows a different player, namely player 1 and player 2, which have their positions in their camera spaces posPlayer1_cam1 and posPlayer2_cam2, respectively. Now, assume that we want to represent a ghost version of player 2 in the camera space of player 1, so that player 1 can see the position of player 2. <i>Which is the position of player 2 in the reference system of camera 1, that is, which is the value of posPlayer2_cam1?</i></div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-O7r-ClYqNkQ/VlQ5Zg8Md4I/AAAAAAAAC0Q/tAj6rjV0nSM/s1600/Imagen5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="306" src="http://1.bp.blogspot.com/-O7r-ClYqNkQ/VlQ5Zg8Md4I/AAAAAAAAC0Q/tAj6rjV0nSM/s400/Imagen5.png" width="400" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: center;">
Figure 1. Problem statement</div>
<div style="text-align: center;">
<br /></div>
<div style="text-align: justify;">
At first sight, the problem seems trivial, and for most cases, it actually is. We simply need to represent the (world) position of player 2 in relation to the camera. Therefore, if the position of player 2 is <i>posPlayer2</i>, and as usual we assume that players belong to layers with <i>scale = 1</i>, we know that:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
posPlayer2_cam1 = posPlayer2 - posCamera1 (1) </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Likewise, the position where the player will be drawn would be:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
posPlayer2_draw = posCamera1 + posPlayer2 - posCamera1 = posPlayer2 (2)</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
And that's it. This is what works in most of the cases.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
However, there is a situation that we need to consider. Assume that there are obstacles with which the players can collide. If these obstacles belong to a layer with<i> scale = 1</i>, then everything works as we've just described. However, if obstacles belong to layers with a different scale, weird things happen. Suppose that obstacles belong to a layer with <i>scale = 2</i>. Then, as we saw in the previous post, advancing the camera <i>u</i> units result in the object being moved <i>2u</i> units to the left. Therefore, if we used simply (1) or (2), player 1 would have the impression that player 2 collides (stops) before reaching the obstacle, as depicted in Figure 2. </div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-hu-xO_WTOLE/VlREtwCF54I/AAAAAAAAC0g/TS8zaEgK2sk/s1600/Imagen6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="290" src="http://1.bp.blogspot.com/-hu-xO_WTOLE/VlREtwCF54I/AAAAAAAAC0g/TS8zaEgK2sk/s400/Imagen6.png" width="400" /></a></div>
<div style="text-align: center;">
<br /></div>
<div style="text-align: center;">
Figure 2. Player 2 reaches the obstacle before it is perceived by player 1</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This is happening because whereas the obstacles are moving with a rate of <i>2u </i>units to the left, player 2 is being moved in camera 1 at a rate of <i>1u </i>unit to the right. Therefore, player 2 reaches the obstacle in camera 2 before it reaches it in camera 1. The solution is moving player 2 in camera 1 at the same rate as the obstacles move but in opposite direction, that is, <i>2u </i>units to the right. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
If obstacles belong to layers with <i>scale = n, 0<n<1</i>, then player 2 would reach the obstacle in camera 1 before it reaches it in camera 2, and player 1 would therefore perceive as if player 2 had run through the obstacle, as depicted in Figure 3.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-axYOLDKv4w8/VlRFBlRmESI/AAAAAAAAC0o/En7amsv_mOA/s1600/Imagen7.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="290" src="http://1.bp.blogspot.com/-axYOLDKv4w8/VlRFBlRmESI/AAAAAAAAC0o/En7amsv_mOA/s400/Imagen7.png" width="400" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: center;">
Figure 3. Player 1 perceives that player 2 run through the obstacle</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Therefore, the solution consists of correcting this displacement: player 2 has to move in camera 1 at the same rate than obstacles. If camera 1 remains still and camera 2 advance <i>u</i> units, player 2 has to be moved <i>2u</i> units to the right in camera 1. If camera 2 remains still and camera 1 advance<i> u</i> units, player 2 has to be moved <i>2u</i> units to the left in camera 1. So the general pattern is: for every unit <i>u</i> of difference between the positions of camera 2 and camera 1, the position of player 2 has to advance <i>2u</i> units. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
posPlayer2_cam1 = posPlayer2_cam2 + 2*(x2 - x1) = posPlayer2 - x2 + 2*(x2 - x1) (3) </div>
<div style="text-align: justify;">
posPlayer2_draw = x1 + posPlayer2_cam1 = x1 + posPlayer2 - x2 + 2*(x2-x1) (4) </div>
<div style="text-align: justify;">
<br />
We can simplify (3) and (4) as follows:<br />
<div style="text-align: center;">
<br /></div>
<div style="text-align: center;">
posPlayer2_cam1 = posPlayer2 + x2 - 2 * x1</div>
<div style="text-align: center;">
posPlayer2_draw = posPlayer2 + x2 - x1</div>
</div>
<div style="text-align: justify;">
<br />
Finally, we can generalize the formulas for a player in a layer with <i>scale = n</i>, and obstacles in a layer with <i>scale = m</i>:<br />
<br />
<div style="text-align: center;">
<b>posPlayer2_cam1 = posPlayer2 + (m - n)*x2 - m*x1</b></div>
<div style="text-align: center;">
<b>posPlayer2_draw = posPlayer2 + (m - n)*x2 + (1 - m)*x1</b> </div>
<br />
And this is all! Hope you enjoyed this series of posts as much as I enjoyed writing it. As I mentioned in the first post, these are the considerations that I took into account while developing the parallax scrolling system for our game to come, Breaking Fast, the result of which you can watch in the following video:<br />
<br />
<br /></div>
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/5CpqVjUNAjc/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/5CpqVjUNAjc?feature=player_embedded" width="320"></iframe></div>
<br /></div>
<div style="text-align: justify;">
See you!</div>
</div>
Anonymoushttp://www.blogger.com/profile/16393413815766208404noreply@blogger.com7tag:blogger.com,1999:blog-3999182258338242021.post-11360930199389671472015-12-10T10:00:00.000+01:002015-12-29T14:38:55.233+01:00Parallax Scrolling in Love2d. Part 2: Testing Collisions in different Layers<div dir="ltr" style="text-align: left;" trbidi="on">
<div>
<div style="text-align: justify;">
Hi all!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This is the second installment of the series on parallax scrolling for Love2d. In the <a href="http://becomingindiedev.blogspot.com.es/2015/11/parallax-scrolling-in-love2d-part-1.html" target="_blank">previous post</a>, we discussed how we could implement parallax scrolling in Love2d, by defining a <i>camera </i>component that was in charge of managing the different layers. In this post, we are going to provide further insight on this implementation and we are going to discuss how we can detect collisions happening between objects that belong to different layers. The gist here is noticing that we have two different, interrelated coordinate systems, and that in order to detect collisions, we must compare the positions of the objects in the same reference frame. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Let's start by defining the two coordinate systems that we have, namely the camera coordinate system, and the world coordinate system. An object will have different values of its position in each system, although it is possible to move from one system to the other by simple mathematical operations. Let's assume that we follow up the example of the last post, in which we wanted the camera to track the player in the center of the screen. Figure 1 shows a diagram that relates the world coordinates with the camera coordinates of the player. We will focus only on the X dimension, but the same reasoning would apply to the Y dimension. Note that we define a world of 10000 x 10000 pixels, where the origin of such world is at the top left corner of the screen. The camera has a dimension of 1920 x 1080 pixels, which corresponds with the standard resolution of most screens today. Every object contained in the camera (the red rectangle) will be visible. As you can see, assuming that the position of the camera in the world is (x, y), the player will have different coordinates in camera space (960) and in world space (x + 960). </div>
<div style="text-align: justify;">
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-L_p_Z8mN7qI/Vk8Gbo7IC-I/AAAAAAAACzo/aQ7kCUHsSqo/s1600/Imagen3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://3.bp.blogspot.com/-L_p_Z8mN7qI/Vk8Gbo7IC-I/AAAAAAAACzo/aQ7kCUHsSqo/s400/Imagen3.png" width="400" /></a></div>
</div>
<div style="text-align: center;">
Figure 1. The player position in camera and world spaces </div>
<div style="text-align: center;">
<br /></div>
<div style="text-align: justify;">
In our example, we assume that the camera is updated as a consequence of the movement of the player (which is logical if we want the camera to track the player). Therefore, this is what happens in each frame:</div>
<ol style="text-align: justify;">
<li>The player presses the right key, which increases the world position of the player by a rate depending on the speed we want the character to have. </li>
<li>As a consequence of the update on the character position, we have to update the world position of the camera, which is advanced the same units as the player has moved. That is, if the player has moved 50 units, the camera will move 50 units. The fact that the camera moves at the same rate as the player is due to the fact that the player belongs to a layer with <i>scale = 1</i>, as we will analyse further in the following.</li>
</ol>
<div style="text-align: justify;">
Given that we update the camera when we update the player, we can consider that the world position* of the camera is a function of the world position of the player, and this function is as follows:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: center;">
posCamera = posPlayer - 960 (1)</div>
<br />
<i>* From now on, we will simply say position when we refer to world position.</i><br />
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
In general, if we have an object that belongs to a layer with a <i>scale = n</i>, the relationship between the position of the object in world and camera space is given by:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: center;">
posObject_cam = posObject - posCamera * n (2)</div>
<div style="text-align: center;">
<br /></div>
<div style="text-align: justify;">
In particular, think of the player, who belongs to a layer of <i>scale = 1</i>. From (1), we have that:</div>
<div style="text-align: justify;">
</div>
<div style="text-align: center;">
posPlayer = posCamera + 960</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Substituting this in (2), we have:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: center;">
posPlayer_cam = posCamera + 960 - posCamera * 1 = 960</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
As we can see, the position of the player in camera space does not depend on the position of the camera, because it is always the same: the center of the screen. Any other object that belongs to a layer with <i>scale = 1</i> will meet (from (2)):</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: center;">
posObject_cam = posObject - posCamera (2a)</div>
<div style="text-align: center;">
<br /></div>
<div style="text-align: justify;">
This means that the position in camera space of the object will change at the same rate that the camera moves. Consider for example a stationary object at position 50. If the camera initially is at position 0, then the object position in camera space will be 50. Now if the camera moves 10 units to the right, the position of the object in camera space would be 50 - 10 = 40. Moving the camera forward <i>u</i> units is equivalent to moving the object backward <i>u</i> units. In the case of the player, it is not a stationary object, but it moves at the same rate as the camera moves, and in particular, the position of the player in camera space is 960 because the difference between the position of the player and the position of the camera is always 960.<br />
<br /></div>
<div style="text-align: justify;">
Consider now the case of stationary objects that belong to a layer with <i>scale = 0</i>. Then, we would have:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: center;">
posObject_cam = posObject - posCamera * 0 = posObject (3)</div>
<div style="text-align: center;">
<br /></div>
<div style="text-align: justify;">
This means that positions of objects that belong to these layers are not affected by changes in the position of the camera: their positions in camera space correspond always to their positions in world space. Or said another way: if a stationary object has the position 10 in camera space, it will keep that same position forever, being the net effect that the object moves at the same rate <i>and same direction</i> as the camera. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Think now of stationary objects that belong to a layer with<i> scale = 2</i>. Then, we have:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: center;">
posObject_cam = posObject - posCamera * 2 (4)<br />
<div style="text-align: left;">
<span style="text-align: justify;"><br /></span></div>
<div style="text-align: justify;">
Let us suppose that the camera moves 10 units to the right. This means that the object in camera space moves -20 units (or 20 units to the left). In general, moving <i>u</i> units the camera to the right is equivalent to moving the object <i>2u</i> units to the left.</div>
<div style="text-align: justify;">
<br />
Once we know how the position of any object in camera space is calculated, let's see something different. Now, we are going to calculate where the objects are actually drawn on the screen. The diagram in Figure 2 helps explaining this:</div>
</div>
<div style="text-align: justify;">
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-eEfatsiYvBs/VlL5nHvYJCI/AAAAAAAAC0A/hST-vYdkuSs/s1600/Imagen4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="192" src="http://2.bp.blogspot.com/-eEfatsiYvBs/VlL5nHvYJCI/AAAAAAAAC0A/hST-vYdkuSs/s400/Imagen4.png" width="400" /></a></div>
<br />
<div style="text-align: center;">
Figure 2. Object positions in different spaces</div>
<br />
Let posObject_draw be the position where an object is drawn on the screen. Clearly, from the diagram above, we have the following:<br />
<br />
<div style="text-align: center;">
posObject_draw = posCamera + posObject_cam </div>
<br />
, where posCamera in the X dimension is <i>x</i>.<br />
<br />
And if we substitute posObject_cam from (2), we get:<br />
<br />
<div style="text-align: center;">
posObject_draw = posCamera + posObject - posCamera * n (5)</div>
<br />
, where <i>n</i> is the scale to which the object belongs.<br />
<br />
Let us instantiate (5) for the player:<br />
<br />
<div style="text-align: center;">
posPlayer_draw = posCamera + posPlayer - posCamera * 1 = posPlayer</div>
<br />
This means that the player is drawn exactly in its world coordinates. If the player advances <i>u</i> units to the right, the player will be drawn these same <i>u</i> units to the right. In the case of stationary objects, this means that they will be drawn always in the same position. Therefore, if the camera advances <i>u</i> units to the right, in order for the object to be in the same position, the object will be drawn <i>u</i> units to the left. Note that this is consistent with the analysis performed on (2a).<br />
<br />
If we instantiate (5) for a stationary object that belongs to a layer with<i> scale = 0</i>, then we have:<br />
<br />
<div style="text-align: center;">
posObject_draw = posCamera + posObject - posCamera * 0 = posCamera + posObject</div>
<br />
This means that the position where this object is drawn moves at the same rate as the camera and in the same direction. The net effect is that the position of the object is not affected by the position of the camera and the object seems to be still. This is consistent with what (3) expressed.<br />
<br />
If we now instantiate an object that belongs to a layer with <i>scale = 2</i>, we would have:<br />
<br />
<div style="text-align: center;">
posObject_draw = posCamera + posObject - posCamera * 2 = posObject - posCamera</div>
<br />
This is expressing that moving <i>u</i> units the camera to the right causes the object to be moved <i>u</i> units to the left, being the net effect that the object is moved <i>2u</i> units to the left, as the analysis in (4) concluded. <br />
<br /></div>
<div style="text-align: justify;">
Once we understand how everything works, it is time to detect collisions among objects in different layers. The key idea here is that we must compare positions of the same type. Let us suppose that we want to check whether two objects <i>A</i> and <i>B</i>, belonging to layers with scales <i>n</i> and <i>m</i>, respectively, are colliding. We have two options:</div>
<ol style="text-align: left;">
<li>Compare positions in camera space.</li>
<li>Compare positions where the objects are actually drawn. </li>
</ol>
</div>
In option 1, the steps would be as follows:<br />
<br />
posA_cam = posA - posCamera * n<br />
posB_cam = posB - posCamera * m<br />
if (colliding(posA_cam, posB_cam)) then ...<br />
<br />
In option 2, we would perform the following steps: <br />
<br />
posA_draw = posA + posCamera * (1 - n)<br />
posB_draw = posB + posCamera * (1 - m)<br />
if (colliding(posA_draw, posB_draw)) then ...<br />
<br />
<div style="text-align: justify;">
Note that given that world coordinates of the objects do not account for the displacement that occurs each frame because of the parallax effect, we cannot use these world coordinates directly for the collision detection. For example, consider two stationary objects <i>A</i> and <i>B</i> that are initially placed in the same (world) position: 500, but <i>A</i> belongs to a layer with <i>scale = 1</i> whereas <i>B</i> belongs to a layer with <i>scale = 2</i>. If we used the world positions to detect collisions between these objects and any other object <i>C</i> that moves toward them, we would detect that <i>C</i> collides with them at the same time, but this is a mistake. Actually, <i>C</i> will reach <i>B</i> in half the time that it will reach <i>A</i>, because <i>B</i> moves twice as faster than <i>A</i> in relation to the camera. In summary: we are using the world position only as an intermediate value to compute the actual position where the objects are drawn (or their position in camera space). </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
And this is all for now. In the<a href="http://becomingindiedev.blogspot.com.es/2015/12/parallax-scrolling-in-love2d-part-3.html" target="_blank"> last installment of the series</a>, we will discuss how we can represent the same object in different camera spaces. This is useful for multiplayer games, where each player has a different view of the world.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Hope you found this interesting and see you soon! </div>
</div>
Anonymoushttp://www.blogger.com/profile/16393413815766208404noreply@blogger.com7tag:blogger.com,1999:blog-3999182258338242021.post-8776031252764869372015-12-05T12:24:00.006+01:002015-12-05T12:24:52.776+01:00Breaking Fast Programming: Press Start Animation<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
Hi all!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I recently uploaded the latest video on the series "Breaking Fast Programming", where we explain how we can achieve an animation for the typical "Press Start" text at the beginning of most games. </div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
As a comment mentioned (thanks, @judelco), there is an error in the final expression:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
theta = theta + 4 * dt % 360</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
, since it should be:</div>
<div style="text-align: justify;">
<br />theta = (theta + 4 * dt) % 360</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Otherwise, we are implicitly writing:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
theta = theta + (4 * dt % 360) </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
because of operator precedence, and theta would grow indefinitely. </div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<iframe width="320" height="266" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/xoJ-ViawqmY/0.jpg" src="https://www.youtube.com/embed/xoJ-ViawqmY?feature=player_embedded" frameborder="0" allowfullscreen></iframe></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
See you!</div>
<div style="text-align: justify;">
FM </div>
</div>
Anonymoushttp://www.blogger.com/profile/16393413815766208404noreply@blogger.com0tag:blogger.com,1999:blog-3999182258338242021.post-13676653302109045652015-12-02T11:34:00.005+01:002015-12-02T11:35:44.354+01:00Breaking Fast Programming on Youtube<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
Hi all!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I am glad to announce that I will be uploading a series of videos on the development of <a href="http://becomingindiedev.blogspot.com.es/2015/10/angry-milk-and-cookies-this-is-breaking.html" target="_blank">Breaking Fast</a>, our current project. For now, you can take a look at the first video, which serves as an introduction to the main programmer (<i>ehem</i>, myself...) and to the game. Although most of the videos will revolve around technical and programming stuff, some videos will explore the development of the art and music of the game. I will keep you posted on new videos to come!</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/_lnMWMdKXuk/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/_lnMWMdKXuk?feature=player_embedded" width="320"></iframe></div>
<br />
<br />
<br /></div>
Anonymoushttp://www.blogger.com/profile/16393413815766208404noreply@blogger.com1tag:blogger.com,1999:blog-3999182258338242021.post-81100229793020787502015-11-27T10:00:00.000+01:002015-11-27T10:00:08.722+01:00Parallax Scrolling in Love2d. Part 1: Data Structures and Programming<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
Hi all!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This is the first post of a series in which I'll explain how we can implement <a href="http://becomingindiedev.blogspot.com.es/2013/09/fundamentals-of-scrolling-part-ii.html" target="_blank">parallax scrolling</a> in <a href="https://love2d.org/" target="_blank">Love2d</a>. The code that I'll share is similar to the one I'm using for <a href="http://becomingindiedev.blogspot.com.es/2015/10/angry-milk-and-cookies-this-is-breaking.html" target="_blank">Breaking Fast</a>, our next game to come.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The implementation builds on the tutorial that you can find <a href="http://nova-fusion.com/2011/04/19/cameras-in-love2d-part-1-the-basics/" target="_blank">here</a>. Actually, I advise you to take a look at this tutorial first, because it covers the fundamental principles behind the implementation. Then, we will perform some extensions, so come back here. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The implementation starts with the idea of creating a data structure that represents the camera. So now, we will focus on a<i> camera.lua</i> file that implements the camera data and functionalities. </div>
<div style="text-align: justify;">
<br />
<i>camera.lua</i><br />
</div>
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> local camera = {}
camera.__index = camera
return camera
</code></pre>
<div style="text-align: justify;">
<br />
What data must a camera have? Well, the first and most important one is the (x,y) coordinates that represent its position. It could also hold data regarding scaling in both directions, and its orientation. If we want the camera to support parallax (and we certainly do), it must also contain a list of layers, where each layer will contain its own objects to be drawn. With this in mind, we can create the camera constructor, as follows:<br />
<br />
<i>camera.lua</i><br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> local function construct()
local self = setmetatable({x = 0, y = 0, scaleX = 1, scaleY = 1, rotation = 0, layers={}}, camera)
return self
end
setmetatable(camera, {__call = construct})
</code></pre>
<br />
As you can see, we are creating a camera with an empty list of layers. Also, with the <i>setmetatable</i> function, we are instructing that if, from some client code, we use the table <i>camera </i>as a function, the method to which <i>__call</i> points is to be invoked. This means that if we want to create two different cameras from client code, we only need to do the following: <br />
<br />
<i>some client code.lua</i><br />
</div>
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> local Camera = require "camera"
myCamera1 = Camera()
myCamera2 = Camera()
</code></pre>
<div style="text-align: justify;">
<br />
Love2d uses three functions to transform the current coordinate system:<br />
<i><br /></i>
<i>love.graphics.rotate( rotation )</i><br />
<i>love.graphics.scale( x_scale, y_scale )</i><br />
<i>love.graphics.translate ( dx, dy )</i><br />
<br />
Let's focus on the last one. According to the <a href="https://love2d.org/wiki/love.graphics.translate" target="_blank">documentation</a>: <i>When this function is called with two numbers, dx, and dy, all the
following drawing operations take effect as if their x and y coordinates
were x+dx and y+dy.</i>
<br />
<br />
So, assume we have a square in the coordinate (1, 0), as shown on the left part of Figure 1. After performing<i> love.graphics.translate( -1, 0 )</i>, we would have the square in the coordinate (1 + (-1), 0 + 0) = (0, 0), because even when we are actually moving the coordinate system, this is equivalent to moving the square in the opposite direction, as depicted on the right side of Figure 1.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-XoPpzYz0dVQ/VkxyLNUG5nI/AAAAAAAACzA/c6-4cMTTFpw/s1600/Imagen1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="157" src="http://3.bp.blogspot.com/-XoPpzYz0dVQ/VkxyLNUG5nI/AAAAAAAACzA/c6-4cMTTFpw/s400/Imagen1.png" width="400" /></a></div>
<br />
<div style="text-align: center;">
Figure 1 </div>
<br />
This is the fundamental mechanism that we can use in order to implement traditional scrolling, where the <i>dx </i>and <i>dy </i>values correspond to the position of the camera with negative sign. The same applies for the scaling and the rotation. We can encapsulate all this in two functions as follows:<br />
<br />
<i>camera.lua</i><br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> function camera:set()
love.graphics.push()
love.graphics.rotate(-self.rotation)
love.graphics.scale(1 / self.scaleX, 1 / self.scaleY)
love.graphics.translate(-self.x, -self.y)
end
function camera:unset()
love.graphics.pop()
end
</code></pre>
<br />
The <i>push()</i> function saves the current transformation on top of a stack, whereas <i>pop()</i> sets the current transformation to the one on top of the stack. The strategy to draw is therefore something similar to this:<br />
<br />
<i>camera.lua</i><br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> function camera:draw()
self:set()
-- draw stuff
self:unset()
end
</code></pre>
<br />
Obviously, prior to calling <i>self:set()</i>, we could modify properties of the camera, in such a way that each draw call behaves different in terms of scaling, rotation or movement/position.<br />
<br />
Let's focus now on the parallax effect. For such effect, we have to turn our attention to the <i>layers. </i>What data must a layer have? First, the layer must be able to draw itself, so it must have a reference to a function that will draw the objects in such a layer. Given that we want that each layer can move at different rates (in order to achieve the parallax effect), each layer must hold a rate or <i>scale </i>value. Finally, it would be interesting that we could decide a relative order among layers, in such a way that we can specify the order in which different layers are drawn. The function that builds a new layer is shown next:<br />
<br />
<i>camera.lua</i><br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> function camera:newLayer(order, scale, func)
local newLayer = {draw = func, scale = scale, order = order}
table.insert(self.layers, newLayer)
table.sort(self.layers, function(a,b) return a.order < b.order end)
return newLayer
end
</code></pre>
<br />
Note that after inserting the new layer into the table of layers, we order them according to the order value. Now, we can complete the draw function as follows:<br />
<br />
<i>camera.lua </i><br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> function camera:draw()
local bx, by = self.x, self.y
for _, v in ipairs(self.layers) do
self.x = bx * v.scale
self.y = by * v.scale
self:set()
v.draw()
self:unset()
end
self.x, self.y = bx, by
end
</code></pre>
<br />
The <i>draw </i>function iterates over all the layers defined for the camera, it then applies a layer scale to the current position of the camera, which makes each layer to be drawn in a possibly different position, depending on the value of this scale. Finally, the <i>draw </i>function of the layer is called. In order to preserve the original position of the camera, we use the temporary variables <i>bx </i>and <i>by</i>.<br />
<br />
Note that given that we are using the product of the layer scale and the current position, stationary objects in layers with <i>scale = 0</i> will have no movement. Therefore, any static background of the game will belong to a layer with such a scale. A layer with <i>scale = 1</i> will contain objects that move at the same rate as the camera (but in the opposite direction). If we want to track a character controlled by the player, a good strategy is including it in a layer with <i>scale = 1</i> and moving it at the same rate as the camera, as we will see later. Anything that moves at a faster or slower rates than the camera will belong to layers with scales greater or lower than 1, respectively. The following post in the series will provide further insight on these statements, but for now, let's see now how some client code can use all of this. Let's assume that we have four layers, that we want to draw in the following order:<br />
<ol>
<li>Static background layer.</li>
<li>Background layer that moves slowly. </li>
<li>Player layer.</li>
<li>Foreground layer with objects moving much faster than the rate at which the player moves.</li>
</ol>
The order is important because elements in the layer <i>n+1</i> will occlude elements in the layer <i>j, 1<=j<n+1 </i>(basically, in all previous layers).<br />
<br />
<i>some client code.lua</i><br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> myCamera1 = Camera()
myCamera1:newLayer(-10, 0, function()
love.graphics.setColor(255, 255, 255)
love.graphics.draw(staticBackground)
end)
myCamera1:newLayer(-5, 0.3, function()
love.graphics.setColor(255, 255, 255)
love.graphics.draw(slowBackground)
end)
myCamera1:newLayer(0, 1.0, function()
love.graphics.setColor(255, 255, 255)
love.graphics.draw(player)
end)
myCamera1:newLayer(10, 1.5, function()
love.graphics.setColor(255, 255, 255)
love.graphics.draw(foreground)
end)
</code></pre>
<br />
Of course this is not the end of the story. Client code is responsible for updating and drawing the contents of the camera. Fortunately, this is easy, as it is shown next:<br />
<br />
<i>some client code.lua</i><br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> function love.draw()
myCamera1:draw()
end
function love.update(dt)
myCamera1:update(dt, player1.posX)
end
</code></pre>
<br />
<i>love.draw</i> and <i>love.update(dt)</i> are two framework callbacks provided by Love2d and which developers can override in order to customize their behaviours. The former will essentially call the <i>draw </i>function that we implemented in the <i>camera.lua </i>module, whereas the <i>update </i>function will in turn call an <i>update</i> function in the <i>camera </i>module, which we haven't discussed yet. In this example, we assume that we want the camera to follow the player when it is in the center of the screen. Achieving this requires adding the following lines to the<i> camera.lua</i> file:<br />
<br />
<i>camera.lua</i><br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> local intendedWidth = 1920
function camera:setPosition(x, y)
self.x = x or self.x
self.y = y or self.y
end
function camera:update(dt, posX)
if posX > intendedWidth / 2 then
self:setPosition(posX - intendedWidth / 2)
else
self:setPosition(0)
end
end
</code></pre>
<br />
Assuming a resolution (<i>intendedWidth</i>) of 1920 pixels in the horizontal dimension, we want to reposition the camera as soon as the player moves past half of this resolution (center of the screen). From that moment onwards, the camera is repositioned each frame to center the player on the screen. As the player belongs to a layer with <i>scale = 1</i>, the player will remain always in the same position in relation to the camera. This again will be further discussed and mathematically proved in the following post of the series. <br />
<br />
And this is for now! I hope you found this tutorial useful. In the next installments of the tutorial, I intend to discuss and provide further insight on three aspects: reasoning about layers scales and their relation with the positions of objects, detecting collisions among objects in different layers and representing objects in different cameras, for example, for local multiplayer games.<br />
<br />
See you! </div>
</div>
Anonymoushttp://www.blogger.com/profile/16393413815766208404noreply@blogger.com13tag:blogger.com,1999:blog-3999182258338242021.post-56824646948161848112015-11-16T13:07:00.003+01:002015-11-16T13:09:56.687+01:00To full-time indie...<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
Hi all!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
A couple of weeks ago, I achieved a milestone that I though it would never arrived: I got my Ph.D. degree in Computer Science. So yes, now I'm a doctor, but not one of those who can prescribe drugs!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This means that a part of my professional life has finished, and now, new opportunities emerge. In particular, this means that I intend to go full-time into indie games development. Of course, this decision entails quite a lot of risks, which are pretty well materialized in a good deal of <a href="http://www.gamasutra.com/blogs/DanielWest/20150908/253040/Good_isnt_good_enough__releasing_an_indie_game_in_2015.php" target="_blank">failure cases</a> and in the so-called <a href="https://medium.com/@morganjaffit/indipocalypse-or-the-birth-of-triple-i-eba64292cd7a" target="_blank">indipocalypse</a>. However, I find myself now in a stage in my life in which I'm willing (and capable) of taking up these risks and the new challenges that are to come. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This also means that I expect to be more active in this blog and in social networks in order to promote our projects, the first of which is the already mentioned <a href="http://becomingindiedev.blogspot.com.es/2015/10/angry-milk-and-cookies-this-is-breaking.html" target="_blank">Breaking Fast</a>. Also, I intend to upload some videos to Youtube in which I will be implementing some new features of this game.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I have set myself a "reflective" deadline of one year, which means that after that year, I will perform a cost-benefit analysis of my decision and I'll take a course of action depending on the outcome of such balance.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-UOLaqwIFd_U/VknG-Rkq7AI/AAAAAAAACys/siilEQAt0rk/s1600/Captura.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="263" src="http://3.bp.blogspot.com/-UOLaqwIFd_U/VknG-Rkq7AI/AAAAAAAACys/siilEQAt0rk/s400/Captura.PNG" width="400" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
So yes, there is no time to lose! I will bring you news about Breaking Fast as soon as I have them. Also you can check our <a href="https://talestudios.wordpress.com/" target="_blank">webpage</a>, which is in a very early stage of development and lack lots of contents yet.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
See you!</div>
<div style="text-align: justify;">
FM</div>
</div>
Anonymoushttp://www.blogger.com/profile/16393413815766208404noreply@blogger.com1tag:blogger.com,1999:blog-3999182258338242021.post-70852294822239351582015-10-14T18:57:00.001+02:002015-10-18T21:58:40.336+02:00Angry milk and cookies... This is Breaking Fast!<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
Hi all!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
It's my pleasure to announce our new game: Breaking Fast (those who think the name is a pun are completely wrong...).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The game can be described as a competitive runner, or even better, as a Mario Kart-like game, where players have to run as fast as they can, avoiding obstacles as well as the attacks received from other players. As usual in our games, the mood of the game revolves around drinks and food, with a casual and friendly artistic style conceived by <a href="https://twitter.com/ManuelaRMontiel?lang=es" target="_blank">Manuela</a>, and music and sounds by <a href="https://olivermoyabueno.bandcamp.com/" target="_blank">Oliver</a>.</div>
<div style="text-align: justify;">
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-Lr_JGzcTdd4/Vh6JLwk6TeI/AAAAAAAACyM/PqblSnJF2b4/s1600/Splash%2BScreen.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="250" src="http://3.bp.blogspot.com/-Lr_JGzcTdd4/Vh6JLwk6TeI/AAAAAAAACyM/PqblSnJF2b4/s400/Splash%2BScreen.png" width="400" /></a></div>
</div>
<div style="text-align: justify;">
Breaking Fast is in an early development state as we are still adding new elements and mechanics to make it even more fun and challenging. Recently, we had the chance to showcase the game in an <a href="http://malagajam.com/malagajam-playday-i/" target="_blank">event for game makers</a> and the feedback was fantastic. People were really hooked on the game and enjoyed playing dirty tricks on their rivals. We also received a good amount of tips to improve the game, and we are currently integrating them. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The video below presents a coarse-grained view of the development process, starting from the conception on pen and paper. We started to think about the game during the last week of July in order to gain some knowledge about the<a href="https://love2d.org/" target="_blank"> Löve2d framework</a>, which we intended to use for the August edition of <a href="http://becomingindiedev.blogspot.com.es/2015/09/drunkula-yet-another-post-mortem-with.html" target="_blank">Ludum Dare</a>. However, we didn't advance much and ended up leaving it aside. Once Ludum Dare finished, we retook it because we were really hopeful about the potential of the game.</div>
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div style="text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/j-QMYoJYVsA/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/j-QMYoJYVsA?feature=player_embedded" width="320"></iframe></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<i>The development of Breaking Fast along three different phases </i></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: justify;">
From its conception, our goal with the game has been targeting the core of fun and competitiveness, providing tight controls that pose a good trade-off between reward and frustration. Once the game is in a more polished state, we intend to submit it to Steam
Greenlight, where we expect to receive even more feedback to finish off the
last details.</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
Currently, the game only supports two players but it is our intent to include support for up to four players. Whether the game will have an online mode will largely depend on the feedback that we receive once in Steam Greenlight, due to the overhead in effort and infrastructure that adding online multiplayer may entail.</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-dou84EZ1Ru4/Vh4rzUyOo3I/AAAAAAAACxY/sOEA3GVwT7U/s1600/IMG_3031.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://2.bp.blogspot.com/-dou84EZ1Ru4/Vh4rzUyOo3I/AAAAAAAACxY/sOEA3GVwT7U/s320/IMG_3031.JPG" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-FvMU43WZMPE/Vh4tiKJttOI/AAAAAAAACx4/lUprn_AGxXo/s1600/IMG_3012.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://1.bp.blogspot.com/-FvMU43WZMPE/Vh4tiKJttOI/AAAAAAAACx4/lUprn_AGxXo/s320/IMG_3012.JPG" width="320" /> </a><a href="http://3.bp.blogspot.com/-h59VT2_R_po/Vh4sHg5iiaI/AAAAAAAACxo/An0RaZe5hCo/s1600/06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="213" src="http://3.bp.blogspot.com/-h59VT2_R_po/Vh4sHg5iiaI/AAAAAAAACxo/An0RaZe5hCo/s320/06.png" width="320" /></a></div>
<div class="" style="clear: both; text-align: center;">
<i>People from all ages and genres enjoying the game </i></div>
</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-ahpm5Of1-Qo/Vh4tiBrR24I/AAAAAAAACx0/Yh_VW7tT4Uk/s1600/IMG_3021.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://2.bp.blogspot.com/-ahpm5Of1-Qo/Vh4tiBrR24I/AAAAAAAACx0/Yh_VW7tT4Uk/s320/IMG_3021.JPG" width="320" /> </a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>This time Cookie beat Milk </i></div>
<div style="text-align: justify;">
<br />
Hope that we aroused your curiosity. We just created a twitter account through which you can <a href="https://twitter.com/tale_studios?lang=es" target="_blank">follow us</a> to stay tuned on the latest updates of Breaking Fast.<br />
<br />
See you.<br />
FM</div>
</div>
Anonymoushttp://www.blogger.com/profile/16393413815766208404noreply@blogger.com0tag:blogger.com,1999:blog-3999182258338242021.post-16118951783196051862015-09-27T13:40:00.002+02:002015-09-27T13:40:35.014+02:00Drunkula: Yet Another Post-Mortem (with nice pictures :))<div dir="ltr" style="text-align: left;" trbidi="on">
<div>
<span style="text-align: justify;">This is an after-the-fact analysis of our experience during our first Ludum Dare, which is divided into three different testimonies coming from three different members/roles in our team.</span><br />
<span style="text-align: justify;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-Utq76k8e_nQ/VgfQ_QiB39I/AAAAAAAACvs/vq5Un7qP6m0/s1600/IMG_2612.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://3.bp.blogspot.com/-Utq76k8e_nQ/VgfQ_QiB39I/AAAAAAAACvs/vq5Un7qP6m0/s320/IMG_2612.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
Welcome to the 33rd edition of Ludum Dare!</div>
<i style="text-align: justify;"><br /></i>
<i style="text-align: justify;">Music & Sound by Oliver</i></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I've been participating in game jams during this year for the first time, and LD is the third one. Drunkula is the eighth soundtrack that I've made for a videogame. And although everything can be improved, I'm really satisfied with the outcome.<br />
<br />
My intention with Drunkula's music was clear: I didn't want a mere background music, but an interesting composition that conveyed the dark atmosphere bound to a vampiric night together with the drunkennes feeling of the main character.<br />
<br /></div>
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-fsblTzC2YwA/VgfRZFYc77I/AAAAAAAACwc/3Wq6oUsJSZ8/s1600/IMG_4813.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://2.bp.blogspot.com/-fsblTzC2YwA/VgfRZFYc77I/AAAAAAAACwc/3Wq6oUsJSZ8/s320/IMG_4813.jpg" width="320" /></a></div>
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-9Xvpf83Eflc/VgfQ_R7iHNI/AAAAAAAACvw/yoAayItRojQ/s1600/IMG_2613.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://1.bp.blogspot.com/-9Xvpf83Eflc/VgfQ_R7iHNI/AAAAAAAACvw/yoAayItRojQ/s320/IMG_2613.jpg" width="320" /></a></div>
<div class="" style="clear: both; text-align: center;">
<br /></div>
<div class="" style="clear: both; text-align: center;">
Setting up our workplace</div>
<div class="" style="clear: both; text-align: center;">
<br /></div>
The composition was the first thing that I did, since it is the most difficult and which takes the longest time. The original instruments are those used for the first two levels. Then, I changed the orchestration to evoke the inners of the chapel (third level) without the need to compose any more pieces. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
For the menu, I cut out a fragment from the theme, changed the instrument of the main theme and I added some audio effects to make it sound like being at the door of a disco. For the credits screen I used a long note in order to simulate that annoying ringing after a night party. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The serious side of the composition is given by:</div>
<div style="text-align: justify;">
<ul>
<li>The choice of D minor because it conveys the feeling of dead and solemnity, like in the Mozart's Réquiem. </li>
<li>The 3/4 beat because it evokes the feeling of an aristocracy hall, like in any J. Strauss' waltz. </li>
<li>The higher dense than usual counterpoint in a jam game in order to convey the overloaded aesthetics usually associated to the vampire's castle, like in the well-known Bach's Toccata and Fugue. </li>
</ul>
<div>
The comical and grotesque side comes from:</div>
<div>
<ul>
<li>The instrumentation, specially with the first two levels trying to represent the outside with wind instruments, and synthesizers and beatbox drums.</li>
<li>The continuous apparent lack of rhythmical beat aims to evoke the drunkennes feeling. For some players, I understand that they felt the music kind of grating, but that was actually the pursued effect. </li>
<li>The slightly funky style of some accompaniments suggests the party mood where the guy that was bitten by the protagonist was. </li>
</ul>
<div>
Some curiosities: </div>
<ul>
<li>Just before closing the loop you can hear the famous "Mmmmm" by Morshu, a character from CDI's Zelda and one of the most parodied characters ever in a videogame. </li>
<li>Hidden among the counterpoint you can here the main theme from Japanese horror movie <i><a href="https://www.youtube.com/watch?v=pTkgS-VA7AQ" target="_blank">Hausu</a></i> (1977), a psychedelic masterpiece that we watched a couple of times during the jam. </li>
<li>The central part has a sequence of chords taken from the beautiful Valse Triste by the Finnish composer Jean Sibelius. </li>
</ul>
<div>
Regarding the sound effects and as I did in the two previous game jams in which I participated, I put off the sound effects till the last day. I used a micro to record elements in the house where we were working and then I edited the sounds in my computer. In this regard, I must thank the level designer because the voices are hers and she assisted me with the foley. To make the voices sound more masculine, I simply lowered the tone by software. Given that the sound effects are the last feature to be implemented, their volume are not so well tuned. The forest environment hardly is perceivable and it's a pity, because that day was very windy and I could record that sound in a natural way with the micro. </div>
</div>
<div>
<br /></div>
</div>
<div>
<div style="text-align: justify;">
<i>Level Design by Esther</i></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The first level was just a tutorial to settle the most basic mechanic of the game: point and click. The second level was about combining two objects to solve the level. In the third screen I introduced another object to solve the level. In this last level I tried to make the game more interesting by increasing a bit the difficulty; hopefully I made it!</div>
</div>
<div style="text-align: justify;">
<br /></div>
<div>
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-65HpNS_RPOI/VgfRB4B5n2I/AAAAAAAACwE/V9A8x5-DlsE/s1600/IMG_4822.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://4.bp.blogspot.com/-65HpNS_RPOI/VgfRB4B5n2I/AAAAAAAACwE/V9A8x5-DlsE/s320/IMG_4822.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
I set up the levels with Tiled map editor, although I designed them previously with diagrams using pixels as units of measurement.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I also aimed to take care of the coherence of spaces between screens; that's why the first screen is on a path, the second one is at the entrance of the fortress and the third one is inside the fortress, not the castle yet but the chapel. I would have liked to have more time to introduce more levels, in a cemetery for example and other screens inside the castle itself: things that I keep in mind if we decide to go on with this game ^_^. I also would have liked to have made some sketches of the environment of the screens, not only the diagram of the level, in order to match the background and the platforms completely in a logical way.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The best thing of the jam for me is that we have learned so much in such a short period of time and have earned lots of experience. I have learned how important is to establish a clear and constant communication with all the members of the team (especially with the artists and the programmers).</div>
<div>
<br /></div>
<div>
<div>
<i>Programming by Manuela and Francisco</i></div>
</div>
<div>
<br /></div>
<div style="text-align: justify;">
We used the Löve2d framework (<a href="https://love2d.org/">https://love2d.org</a>) because we were interested in grasping a better understanding of Lua, a programming language that has been gaining traction among the game development communities during the last years. The main advantage of this choice is that we actually learned a lot about Lua, but the setback (and we were aware of it) is that we needed to build almost everything up from scratch. Given that we had no previous experience with a game jam, and that we had no pre-existing modules or data structures, we were a bit scared that we couldn’t make it to the deadline. Fortunately, this same deadline gave us the productivity boost that we needed to finish everything off. That’s definitely a good thing about jams!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The workflow that we used was the following. The artists handed their assets to the level designer, who used the <a href="http://www.mapeditor.org/" target="_blank">Tiled Map Editor</a> to set up the level. Then, the level, together with collision information, was exported to a lua format that we could read and show on screen. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/--5nyL96GtDk/VgfSjsGCTKI/AAAAAAAACwo/ugWIEPVZfBs/s1600/IMG_4817.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://1.bp.blogspot.com/--5nyL96GtDk/VgfSjsGCTKI/AAAAAAAACwo/ugWIEPVZfBs/s320/IMG_4817.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
Having a strong breakfast was important!</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
As for the programming tasks, we started off by loading a simplified version of a level and showing a placeholder sprite for the main character (in particular, an 8-bit Mario sprite…). Then, we made sure that we could read an actual level from the Tiled Map Editor application and that we could show it on screen. Later, we added the main character and the basic collision systems to keep it from falling. In parallel, we tested the <a href="https://github.com/kikito/anim8" target="_blank">anim8</a> library for loading and showing some animations packed in grids (i.e. spritesheets). Also in parallel, we created the transition system for the different screens and for the introduction, and we integrated the music and sound effects in the last hours. Finally, we had to face some bugs with the change of direction of gravity, but we mostly fixed them all.<br />
<br /></div>
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-1OTAuHfKMOY/VgfQ_iuRYCI/AAAAAAAACv4/dHgzz8ZYWqA/s1600/IMG_3390.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="213" src="http://2.bp.blogspot.com/-1OTAuHfKMOY/VgfQ_iuRYCI/AAAAAAAACv4/dHgzz8ZYWqA/s320/IMG_3390.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-XlXTnLJkWK8/VgfRAkD8KcI/AAAAAAAACwU/68dUhdE8ug0/s1600/IMG_3391.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="213" src="http://3.bp.blogspot.com/-XlXTnLJkWK8/VgfRAkD8KcI/AAAAAAAACwU/68dUhdE8ug0/s320/IMG_3391.jpg" width="320" /></a></div>
<br /></div>
<div style="text-align: justify;">
Stuff that we liked:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
- The workflow was well established from the beginning, and all the members of the team took up their roles perfectly.</div>
<div style="text-align: justify;">
- We learned a lot about the Lua language, and the Löve2d framework, which has proven to be very useful not only for game prototyping, but also for the creation of full-fledged games. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Improvable stuff:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
- We didn’t take advantage of all the features of Tiled Map Editor, since we only used it to set up the map and the polylines for simple collisions.</div>
<div style="text-align: justify;">
- More play testing would have been beneficial, as some silly bugs could have been identified easily before release.</div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-mvUWtZyBgMo/VgfS3NiYYvI/AAAAAAAACww/RSNihs1-L-A/s1600/IMG_3006.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://4.bp.blogspot.com/-mvUWtZyBgMo/VgfS3NiYYvI/AAAAAAAACww/RSNihs1-L-A/s320/IMG_3006.jpg" width="180" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
In the end, this was our results: we were in Q1, which is pretty cool being the first time</div>
<br /></div>
<div>
<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<span style="background-color: white; color: #222222; font-family: arial, sans-serif; font-size: 13px;"><br /></span></div>
</div>
</div>
Anonymoushttp://www.blogger.com/profile/16393413815766208404noreply@blogger.com0tag:blogger.com,1999:blog-3999182258338242021.post-67615001406276934952015-09-04T12:32:00.001+02:002015-10-18T21:59:04.210+02:00Drunkula, our Ludum Dare Game<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
Hi!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
It's my pleasure to introduce you <a href="http://ludumdare.com/compo/ludum-dare-33/?action=preview&uid=54805" target="_blank">Drunkula</a>, a game that I made with a team of friends in 72 hours for the <a href="http://ludumdare.com/compo/" target="_blank">Ludum Dare</a>. As I explained in an <a href="http://becomingindiedev.blogspot.com.es/2013/08/ludum-dare-or-how-to-force-yourself-to.html" target="_blank">earlier post</a>, Ludum Dare is an excellent way of forcing yourself to start and finish a game, and I advise any game developer to participate in this and other game jams. Our experience has been fantastic and I intend to write a post about this experience and what it took to make the game in the near future.</div>
<div style="text-align: justify;">
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-Gi3nJYGuEjk/VemA8P5T2nI/AAAAAAAACvI/0gRNmv1LD8Y/s1600/Cabecera%2BDrunkula.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="105" src="http://1.bp.blogspot.com/-Gi3nJYGuEjk/VemA8P5T2nI/AAAAAAAACvI/0gRNmv1LD8Y/s400/Cabecera%2BDrunkula.png" width="400" /></a></div>
<br /></div>
<div style="text-align: justify;">
For now, you can take a look at the game and leave us a honest feedback if you please. Yes, it is short. Yes, there are glitches. But I think that the overall result is more than good for such tight deadline. :)</div>
<div style="text-align: justify;">
<br /></div>
Drunkula is a puzzle adventure about a drunk vampire (because he bit a drunk guy) who wants to get back to his coffin in his castle. You have to help him by clicking objects on the screen. You can also check the game on <a href="http://gamejolt.com/games/drunkula/89708" target="_blank">GameJolt</a>.<br />
<div>
<br /></div>
There are also a couple of Let's play videos uploaded by Youtubers, in case you prefer to take a quick look. You can watch one of these below.<br />
<div>
<br /></div>
<div>
See you!</div>
<div>
FM</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/mDiageLQ3zk/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/mDiageLQ3zk?feature=player_embedded" width="320"></iframe></div>
</div>
Anonymoushttp://www.blogger.com/profile/16393413815766208404noreply@blogger.com0tag:blogger.com,1999:blog-3999182258338242021.post-42983495061003452922015-08-20T13:42:00.002+02:002015-08-20T13:42:16.116+02:00Starting Engines for Ludum Dare<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
Hi!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
These days I've been getting ready for the <a href="http://ludumdare.com/compo/" target="_blank">Ludum Dare</a> game jam, the theme of which will be announced next Saturday at 3 a.m. (Spanish local time). As part of my training, I've been learning a little bit about <a href="https://love2d.org/" target="_blank">Love2d</a>, a Lua-based game framework that is proving to be a powerful tool not only for mechanics prototyping but also for full-fledged game development. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
As part of this training, I'm developing (again together with <a href="https://www.behance.net/manuela-ruiz" target="_blank">Manuela</a>) a local multiplayer game, which I'll show you more about after the jam, because I'll likely not have time to finish it off before this weekend. However, I can share with you some early art created by Manuela. Yes yes yes... more food... again :)</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-Cp_xrdSHRxw/VdW8jw1mipI/AAAAAAAACuw/F2C_UqoaV2U/s1600/blog.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://3.bp.blogspot.com/-Cp_xrdSHRxw/VdW8jw1mipI/AAAAAAAACuw/F2C_UqoaV2U/s320/blog.png" width="320" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
See you!</div>
<div style="text-align: justify;">
FM</div>
</div>
Anonymoushttp://www.blogger.com/profile/16393413815766208404noreply@blogger.com2tag:blogger.com,1999:blog-3999182258338242021.post-43031182741148328862015-07-27T12:54:00.000+02:002015-07-27T12:56:56.070+02:00Gamepolis 2015: An Overview<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
Hi all!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
As promised, here it is my experience during the 2015 edition of Gamepolis. (<i>To check my course during the previous editions, click <a href="http://becomingindiedev.blogspot.com.es/2013/07/gamepolis-friday.html" target="_blank">here</a> and <a href="http://becomingindiedev.blogspot.com.es/2014/07/gamepolis-2014-overview.html" target="_blank">here</a></i>). </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The event came this year with some interesting novelties:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
1) More national and international projection: not only did the number of attendees increase, but also the variety of their origin, which encompassed many Spanish regions. Long lines, especially during the morning, showed the increasing interest in this event, as shown in Figure 1. Also, the invited speaker <a href="https://en.wikipedia.org/wiki/Petro_Tyschtschenko" target="_blank">Petro Tyschtschenko</a> provided the international flavour with his nostalgic speech about the <a href="https://en.wikipedia.org/wiki/Amiga" target="_blank">Amiga</a> in its 30th anniversary. </div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-gow45g6S1r0/VbYJROeW3tI/AAAAAAAACtU/XIITjTLF0BY/s1600/IMG_2065.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="http://2.bp.blogspot.com/-gow45g6S1r0/VbYJROeW3tI/AAAAAAAACtU/XIITjTLF0BY/s320/IMG_2065.JPG" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
Figure 1. Tons of people lined up to access the premises, and more than half of the line </div>
<div class="separator" style="clear: both; text-align: center;">
cannot be seen from this perspective!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
2) <a href="http://gameinvest.es/" target="_blank">GameInvest</a> Forum: co-located with Gamepolis, GameInvest provided a forum where developers could show their games to investors. As part of the agenda, there were some interesting talks on game investment and financial aids. Particularly interesting was a roundtable discussion about the aspects that investors often examine when making investment decisions. The main conclusion was that the game developer experience is usually graded with the highest priority. Thus, when an investor is faced with whether to invest in an unexperienced game developer with a brilliant idea, or in an experienced developer with a not so good idea, the odds will mostly be in favour of the latter (in many cases, unfortunately). </div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-JoxLGMkgU40/VbYJQH1Us4I/AAAAAAAACtc/gjjJVXV5L4o/s1600/IMG_2033.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://2.bp.blogspot.com/-JoxLGMkgU40/VbYJQH1Us4I/AAAAAAAACtc/gjjJVXV5L4o/s320/IMG_2033.JPG" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
Figure 2. GameInvest Forum</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
3) Game Jam: <a href="http://malagajam.com/" target="_blank">MalagaJam</a> is a young association targeted at game developers, which is based in Malaga physically and in Internet digitally. Two weeks ago, they organized their second Game Jam, the awards of which were announced during a Gamepolis session on Sunday afternoon. The list of games and their download links are <a href="https://itch.io/jam/malagajam-weekend-2" target="_blank">here</a>. One of the most successful games, <a href="http://moitapecha.itch.io/panspermia" target="_blank">Panspermia</a>, achieved The Most Outstanding Visuals and to The Best Audio and Music awards, the latter of which was thanks to my friend Oliver (Figure 4). </div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-ndruIxv6Y04/VbYJRbg_b8I/AAAAAAAACto/Y4bGLIJGnDs/s1600/IMG_2036.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://4.bp.blogspot.com/-ndruIxv6Y04/VbYJRbg_b8I/AAAAAAAACto/Y4bGLIJGnDs/s320/IMG_2036.JPG" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
Figure 3. The auditorium was completely crowded during the jam awards ceremony</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-EElUzdEv1R0/VbYHnNH2n-I/AAAAAAAACs4/4M1Vo7B6kSc/s1600/oliJam.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="http://4.bp.blogspot.com/-EElUzdEv1R0/VbYHnNH2n-I/AAAAAAAACs4/4M1Vo7B6kSc/s320/oliJam.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
Figure 4. Panspermia team receiving The Best Audio and Music award.</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div style="text-align: justify;">
Contrary to the previous editions, in which I tried to turn up at almost all the conferences, this year I could barely attend any one. The reason is that I participated in GameInvest with a project called GalaxyNumbers (Figures 5 and 6), for which I'm the programmer. The game combines match-3 mechanics (Tetris) with a Candy Crush aesthetics and presents an interesting mathematical twist. According to the people that could play the game during the event, it is fun and addictive, and these people would repeatedly ask us whether the game was already available for download. Unfortunately, we always had to answer "not yet". Precisely the idea of participating in GameInvest was to request investment to polish the last details and to integrate the last features, and also to cover marketing efforts. For now, we are happy to have received very positive feedback from a broad range of users.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-x72asQrNF9k/VbYJQAIcRDI/AAAAAAAACtk/cVV1cT0LhJs/s1600/IMG_2006.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://3.bp.blogspot.com/-x72asQrNF9k/VbYJQAIcRDI/AAAAAAAACtk/cVV1cT0LhJs/s320/IMG_2006.JPG" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
Figure 5. The stand of Galaxy Numbers</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-66Ao9zk1_x4/VbYJQIIfw7I/AAAAAAAACtQ/dYwsdlquUQI/s1600/IMG_2014.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://3.bp.blogspot.com/-66Ao9zk1_x4/VbYJQIIfw7I/AAAAAAAACtQ/dYwsdlquUQI/s320/IMG_2014.JPG" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
Figure 6. The presentation of Galaxy Numbers</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
As a wrap-up, this edition of Gamepolis has provided a bigger focus on developers and has widened its impact by bringing an international, well-known speaker, which were two aspects that remained uncovered in the two previous editions and which I criticized in those posts.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-Rsy83NuNHj4/VbYK8odEmFI/AAAAAAAACtw/WlXZ05GpQTc/s1600/IMG_2035.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://2.bp.blogspot.com/-Rsy83NuNHj4/VbYK8odEmFI/AAAAAAAACtw/WlXZ05GpQTc/s320/IMG_2035.JPG" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
Figure 7. A 3D printer making cool stuff. Actually, the game jam awards were printed!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Something to improve? Well, there are some sources that have complained about the lack of respect of a reduced number of attendees during some conferences, who would not stop their chattering. I would therefore suggest enforcing a bigger control during the presentations, as well as continuing the effort towards a wider internationalization.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-JTzzrHWK21Q/VbYNQxbZd7I/AAAAAAAACt8/waCuJ15gXVw/s1600/CK2TVt7WEAE0yOV.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="http://1.bp.blogspot.com/-JTzzrHWK21Q/VbYNQxbZd7I/AAAAAAAACt8/waCuJ15gXVw/s320/CK2TVt7WEAE0yOV.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
Figure 8. A minute of silence was observed in memory of Mr. Iwata, followed by a huge ovation. RIP.</div>
<div style="text-align: justify;">
<br /></div>
</div>
Anonymoushttp://www.blogger.com/profile/16393413815766208404noreply@blogger.com0