tag:blogger.com,1999:blog-91216422400259588322024-03-18T14:22:10.940-07:00Trystan's blogTrystanhttp://www.blogger.com/profile/15653418292042541807noreply@blogger.comBlogger130125tag:blogger.com,1999:blog-9121642240025958832.post-91671855689764853142016-01-21T20:27:00.000-08:002016-01-21T20:31:16.068-08:00roguelike tutorial 00: The table of contentsPeople seem to like my roguelike tutorial!<div>
<br /></div>
<div>
For those who want to try making your own roguelike in java, here's the links to each of the 20 posts in my little tutorial I did a few years ago. I try to take it one small step at a time, explain why I'm doing what I'm doing, teach a bit of programming, and move forward with each post.</div>
<div>
<br /></div>
<div>
<a href="http://trystans.blogspot.com.br/2011/08/roguelike-tutorial-01-java-eclipse.html">01 Java, Eclipse, AsciiPanel, application, applet</a></div>
<div>
<a href="http://trystans.blogspot.com.br/2011/08/roguelike-tutorial-02-input-output.html">02 input, output, modes, and screens</a></div>
<div>
<a href="http://trystans.blogspot.com.br/2011/08/roguelike-tutorial-03-scrolling-through.html">03 scrolling through random caves</a></div>
<div>
<a href="http://trystans.blogspot.com.br/2011/08/roguelike-tutorial-04-player.html">04 the player</a></div>
<div>
<a href="http://trystans.blogspot.com.br/2011/09/roguelike-tutorial-05-stationary.html">05 stationary monsters</a></div>
<div>
<a href="http://trystans.blogspot.com.br/2011/09/roguelike-tutorial-06-hitpoints-combat.html">06 hitpoints, combat, and messages</a></div>
<div>
<a href="http://trystans.blogspot.com.br/2011/09/roguelike-tutorial-07-z-levels-and.html">07 z levels and deeper caves</a></div>
<div>
<a href="http://trystans.blogspot.com.br/2011/09/roguelike-tutorial-08-vision-line-of.html">08 vision, line of sight, and field of view</a></div>
<div>
<a href="http://trystans.blogspot.com.br/2011/09/roguelike-tutorial-09-wandering.html">09 wandering monsters</a></div>
<div>
<a href="http://trystans.blogspot.com.br/2011/09/roguelike-tutorial-10-items-inventory.html">10 items, inventory, inventory screens</a></div>
<div>
<a href="http://trystans.blogspot.com.br/2011/09/roguelike-tutorial-11-hunger-and-food.html">11 hunger and food</a></div>
<div>
<a href="http://trystans.blogspot.com.br/2011/09/roguelike-tutorial-12-weapons-and-armor.html">12 weapons and armor</a></div>
<div>
<a href="http://trystans.blogspot.com.br/2011/09/roguelike-tutorial-13-aggressive.html">13 aggressive monsters</a></div>
<div>
<a href="http://trystans.blogspot.com.br/2011/10/roguelike-tutorial-14-experience-and.html">14 experience and leveling up</a></div>
<div>
<a href="http://trystans.blogspot.com.br/2011/10/roguelike-tutorial-15-help-examine-and.html">15 help, examine, and look screens</a></div>
<div>
<a href="http://trystans.blogspot.com.br/2011/10/roguelike-tutorial-16-throwing-and.html">16 throwing and ranged weapons</a></div>
<div>
<a href="http://trystans.blogspot.com.br/2011/10/roguelike-tutorial-17-smarter-monsters.html">17 smarter monsters</a></div>
<div>
<a href="http://trystans.blogspot.com.br/2011/10/roguelike-tutorial-18-potions-and.html">18 potions and effects</a></div>
<div>
<a href="http://trystans.blogspot.com.br/2011/10/roguelike-tutorial-19-mana-spells-and.html">19 mana, spells, and magic books</a></div>
<div>
<a href="http://trystans.blogspot.com.br/2011/10/roguelike-tutorial-20-item-appearance.html">20 item appearance and identification</a></div>
<div>
<br /></div>
<div>
And, because it's always a good idea to pause and reflect:</div>
<div>
<a href="http://trystans.blogspot.com.br/2011/10/roguelike-tutorial-retrospective.html">roguelike tutorial retrospective</a></div>
<div>
<br /></div>
<div>
When you make something cool, or even come up with a neat idea, let us know on <a href="https://www.reddit.com/r/roguelikedev/">/r/roguelikedev/</a>!</div>
Trystanhttp://www.blogger.com/profile/15653418292042541807noreply@blogger.com388tag:blogger.com,1999:blog-9121642240025958832.post-43049906146483388952015-01-12T23:20:00.000-08:002015-01-12T23:20:50.108-08:00A bit of progress on the island.I'm focusing on making a playable alpha version this month: usability, balance, polish, a bit more content, stuff like that. I usually hate blogposts that are just a list but here you go.<br />
<br />
Completed this week:<br />
<ul>
<li>start screen</li>
<li>help screen</li>
<li>r.i.p screen</li>
<li>worldgen screen</li>
<li>death from too little food</li>
<li>death from too much food</li>
<li>death from too little water</li>
<li>death from too much water</li>
<li>death from too little stamina</li>
<li>death from too much stamina</li>
</ul>
<div>
<br /></div>
<div>
Remaining to do items:</div>
<ul>
<li>death from being too cold for too long</li>
<li>death from being too hot for too long</li>
<li>save</li>
<li>load</li>
<li>day/night transitions</li>
<li>map screen only shows what you have explored</li>
<li>show vague data instead of exact on play screen (morning instead of 6:42, hot instead of 98 deg, thirsty instead of 100/1000 etc.)</li>
<li>message log</li>
<li>instead of consuming the entire plant, place it - or parts of it - in inventory</li>
<li>eat parts of plants in inventory</li>
<li>replant plants from inventory</li>
<li>inland lakes and ponds</li>
<li>saltwater/freshwater</li>
<li>drinking freshwater is good, drinking saltwater is bad</li>
<li>rework and balance weather</li>
<li>rework and balance hunger, thirst, and exhaustion</li>
<li>make some plants grow next to same kind</li>
<li>add plant types and stats</li>
<li>status effects form stats being too low or too high for too long</li>
<li>status effects from eating certain plants</li>
<li>remove many hard-coded worldgen parameters</li>
<li>worldgen options</li>
<li>add caves</li>
<li>add ruins</li>
</ul>
Trystanhttp://www.blogger.com/profile/15653418292042541807noreply@blogger.com32tag:blogger.com,1999:blog-9121642240025958832.post-10752070340004427552015-01-05T18:27:00.005-08:002015-01-05T18:27:42.094-08:00Hunger and thirst on the islandI didn't have much time this week but managed to change how elevation is handled and added some basic stats.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5-4xia2fCjwiYzVZ4qryi6vYbXeuPIMTRHZX9M0R8MzjsaWYeSEG30br6a-lVXofUqe2ea7KzLJB59yoFFY-K9Lc42p6JgIHVEjQHOv46t3z2LFWT5kVEBWhA4kFvdu2ZpcqZg2WW3-Q/s1600/Screen+Shot+2015-01-05+at+5.56.25+PM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5-4xia2fCjwiYzVZ4qryi6vYbXeuPIMTRHZX9M0R8MzjsaWYeSEG30br6a-lVXofUqe2ea7KzLJB59yoFFY-K9Lc42p6JgIHVEjQHOv46t3z2LFWT5kVEBWhA4kFvdu2ZpcqZg2WW3-Q/s1600/Screen+Shot+2015-01-05+at+5.56.25+PM.png" height="392" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Hurting from walking on thorny bushes near a mountain.</td></tr>
</tbody></table>
<br />
There's still different levels of height in the lowlands but after a certain height (8 or 9 I think) it changes into solid mountain. I think it's a decent compromise that allows the simplicity of not having real z-levels but still having small slopes and mountainsides to dig through. Eventually the mountains will have caves and the lowlands will have ruins and other things to explore.<br />
<br />
You can now eat plants to replenish your food, drink water to replenish your water, and sleep to replenish stamina. Thorny plants have a chance to reduce your hp when walking through them, tangled plants have a chance to prevent your from walking through them, and other plants will affect your hunger, thirst, and stamina when eaten.<br />
<br />
Not bad for one month.<br />
<br />
<hr />
<br />
This month I'll focus on making a playable alpha version.<br />
<br />
Vague to do list:<br />
<ul>
<li>start screen</li>
<li>help screen</li>
<li>r.i.p screen</li>
<li>worldgen screen</li>
<li>death from too little food</li>
<li>death from too much food</li>
<li>death from too little water</li>
<li>death from too much water</li>
<li>death from too little stamina</li>
<li>death from too much stamina</li>
<li>death from being too cold for too long</li>
<li>death from being too hot for too long</li>
<li>save</li>
<li>load</li>
<li>day/night transitions</li>
<li>map screen only shows what you have explored</li>
<li>show vague data instead of exact on play screen (morning instead of 6:42, hot instead of 98 deg, thirsty instead of 100/1000 etc.)</li>
<li>message log</li>
<li>instead of consuming the entire plant, place it - or parts of it - in inventory</li>
<li>eat parts of plants in inventory</li>
<li>replant plants from inventory</li>
<li>inland lakes and ponds</li>
<li>saltwater/freshwater</li>
<li>drinking freshwater is good, drinking saltwater is bad</li>
<li>rework and balance weather</li>
<li>rework and balance hunger, thirst, and exhaustion</li>
<li>make some plants grow next to same kind</li>
<li>add plant types and stats</li>
<li>status effects form stats being too low or too high for too long</li>
<li>status effects from eating certain plants</li>
<li>remove many hard-coded worldgen parameters</li>
<li>worldgen options</li>
<li>add caves</li>
<li>add ruins</li>
</ul>
Trystanhttp://www.blogger.com/profile/15653418292042541807noreply@blogger.com23tag:blogger.com,1999:blog-9121642240025958832.post-58441508307144549602014-12-29T17:30:00.001-08:002014-12-29T17:30:05.026-08:00Little progress on the islandI added z-levels to the island so I could add caves and towers and eventually large trees. But it was really slow and I wasn't too happy with the direction it was moving things. The performance was worse, the code became bloated, and it didn't add anything fun or neat or new. So I'm going to revert this week's work and save z-levels for later.<br />
<br />
I may get rid of elevation all together - I don't know. I'm not sure what it would add gameplay wise and this is starting to turn more into a simulation than a game. Sims are fine but I want a fun roguelike game, not a SimEarth wannabe or a lame Dwarf Fortress.<br />
<br />
I think I'll focus on making it a playable game now. You know, add ways to suffer die.Trystanhttp://www.blogger.com/profile/15653418292042541807noreply@blogger.com4tag:blogger.com,1999:blog-9121642240025958832.post-30779928127646092102014-12-21T19:04:00.001-08:002014-12-21T19:04:10.876-08:00Randomized plants on the islandThe island now has some random plant life!<br />
<br />
During worldgen a few dozen plant species are generated. Each species has an ideal elevation, precipitation, terrain type, and a few other stats. The world is then populated based on how well each species is adapted to each location.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgr-jfwzfmxeO-HPLd_6q-Wh3mcij7o24MG7vbOU-GIP8bKQiZUK7Qc21mKG4iOmk9OLRCV1RJxeQNoX13HTZZD-pwh9SxMmHtLXp6gBagrA2sAaB3ECubLUWjhl3nDtlP4zG3W0eEzXcs/s1600/Screen+Shot+2014-12-21+at+6.22.30+PM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgr-jfwzfmxeO-HPLd_6q-Wh3mcij7o24MG7vbOU-GIP8bKQiZUK7Qc21mKG4iOmk9OLRCV1RJxeQNoX13HTZZD-pwh9SxMmHtLXp6gBagrA2sAaB3ECubLUWjhl3nDtlP4zG3W0eEzXcs/s1600/Screen+Shot+2014-12-21+at+6.22.30+PM.png" height="392" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Map view of the dominant flora of the island.</td></tr>
</tbody></table>
<br />
<br />
Each species also gets a few traits chosen at random. Here's a few examples:<br />
<ul>
<li>Desert - they get a bonus for living in areas with low precipitation.</li>
<li>Red - changes the color a bit.</li>
<li>Stone - they get a bonus for living on stone.</li>
<li>Succulent - eventually, consuming them will give you more water.</li>
<li>Tangled - eventually, walking through them will have a chance of restricting your movement.</li>
<li>Thorny - eventually, walking through them will cause a small amount of damage.</li>
</ul>
<div>
Every turn some plants die and some plants are born based on weather, luck, and competition for space with other species. </div>
<div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpMitESE50QhyphenhyphenNaflO-tI8Gtf1Opz5Pwfl3Lyb11jayZfqq0UKTmw8CCM0zEQHi9MgcZWGDO-6nnyRWoy2PiF9wQCmOMWkfwnWyNoH6NRtSAS8zY7YapyT9C37dKDRY0JgzDfzyK90ULc/s1600/Screen+Shot+2014-12-21+at+6.15.39+PM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpMitESE50QhyphenhyphenNaflO-tI8Gtf1Opz5Pwfl3Lyb11jayZfqq0UKTmw8CCM0zEQHi9MgcZWGDO-6nnyRWoy2PiF9wQCmOMWkfwnWyNoH6NRtSAS8zY7YapyT9C37dKDRY0JgzDfzyK90ULc/s1600/Screen+Shot+2014-12-21+at+6.15.39+PM.png" height="392" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Top of a hill with few plants.</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJJHsz27At-SkEQh-GVRnF5vlnajl7jhQ91OSNlYlgQEkvgACzspJcRkOOBD95NYiKY6mxz-yscvZ4fXH7vK2aRKDecJ87_wLKN0evc7i6f6kN_vGY1HPH7kbvqZoUxxPo0UeJtpG7rnA/s1600/Screen+Shot+2014-12-21+at+7.01.42+PM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJJHsz27At-SkEQh-GVRnF5vlnajl7jhQ91OSNlYlgQEkvgACzspJcRkOOBD95NYiKY6mxz-yscvZ4fXH7vK2aRKDecJ87_wLKN0evc7i6f6kN_vGY1HPH7kbvqZoUxxPo0UeJtpG7rnA/s1600/Screen+Shot+2014-12-21+at+7.01.42+PM.png" height="392" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A light winter shower and more plants.</td></tr>
</tbody></table>
<br /></div>
<div>
Part of surviving on the island will be finding what plants are useful. Which are safe to eat, which can be used to make poisons, which can be used to make rope or cloth, which should be avoided, etc.</div>
<div>
<br /></div>
<div>
There's no trees yet though. I'm not sure how I want trees to work so I'm saving that for later.</div>
Trystanhttp://www.blogger.com/profile/15653418292042541807noreply@blogger.com5tag:blogger.com,1999:blog-9121642240025958832.post-48416157550421939012014-12-14T16:40:00.002-08:002014-12-14T16:40:47.978-08:00Time, weather, and geography on the islandI implemented time, some seasonal weather, and a small bit of geology this week.<br />
<br />
<br />
<b>Time and seasons. </b>Time on the island is pretty straightforward. One turn equals one minute. 1440 minutes in a day, one day per season, and 12 seasons a year for a total of 17,280 turns per year.<br />
<br />
One thing I haven't decided is how to implement night time. I could slowly redden and darken the tiles as the sun sets, shrink the view distance, or maybe do something else. Any ideas?<br />
<br />
<br />
<b>Climate and weather. </b>Most weather on the island is a mix of calculations and simulation. Idealized temperature, cloudiness, and precipitation is calculated by adding sine waves for seasonal variation.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBGMAJU5szuEG_Oq3myt9BVKjPm_i8ZdaSf31-vH91atmc8CczrVMrawJx07sA7qebIlGv-nlo8R8xLWyAMpv0doMtaquBoQ8W1Y_oxGZFBl4KRyYpJc3-ZwZOLhbkCfHnhu7YCw0uDh4/s1600/Screen+Shot+2014-12-14+at+4.32.45+PM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBGMAJU5szuEG_Oq3myt9BVKjPm_i8ZdaSf31-vH91atmc8CczrVMrawJx07sA7qebIlGv-nlo8R8xLWyAMpv0doMtaquBoQ8W1Y_oxGZFBl4KRyYpJc3-ZwZOLhbkCfHnhu7YCw0uDh4/s1600/Screen+Shot+2014-12-14+at+4.32.45+PM.png" height="280" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Sine waves added together.</td></tr>
</tbody></table>
<br />
Throw in a bit of randomness and minor feedback from the island height map and you get some interesting things. For example, the ideal temperature is the sum of a daily cycle, yearly cycle, and a short, medium, and long term cycle. The real temperature also includes elevation, cloud cover, and the previous temperature. Current precipitation is affected by random seasonal variation, local geography, temperature, and where the clouds currently are.<br />
<br class="Apple-interchange-newline" />
This is all simulated at the map level, which is now a 60x60 grid, and rain and snow are animated on the screen when walking around.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgaF5HqoYYbrT4eNz2AyQPzqi-Y9TfFvKzu4YEuOkV9Fzks_EZA6Zzn3XDK-BwRElwTaXGYQy6hEhyphenhyphenRuVEMoDIUy4ifiFdPSBLffxbBvom7t-_8V2-ekphkNwRWnAiw4nKt31eoKbkU5k/s1600/Screen+Shot+2014-12-14+at+3.54.10+PM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgaF5HqoYYbrT4eNz2AyQPzqi-Y9TfFvKzu4YEuOkV9Fzks_EZA6Zzn3XDK-BwRElwTaXGYQy6hEhyphenhyphenRuVEMoDIUy4ifiFdPSBLffxbBvom7t-_8V2-ekphkNwRWnAiw4nKt31eoKbkU5k/s1600/Screen+Shot+2014-12-14+at+3.54.10+PM.png" height="392" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Elevation view of an island.</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibvsAcDaYiBnQSBTa-HuYMZdWzZeBmfNW11R-fT7C52PO3XD-wosdFt1ynJFddIROn0ySu8FfAXHgnb_JPL8XPp8-VMSo6u4O-Rd-6u7S8rhZbuTIXd-zXxwD4qTVM-nNCC11VVeR6QD0/s1600/Screen+Shot+2014-12-14+at+3.54.18+PM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibvsAcDaYiBnQSBTa-HuYMZdWzZeBmfNW11R-fT7C52PO3XD-wosdFt1ynJFddIROn0ySu8FfAXHgnb_JPL8XPp8-VMSo6u4O-Rd-6u7S8rhZbuTIXd-zXxwD4qTVM-nNCC11VVeR6QD0/s1600/Screen+Shot+2014-12-14+at+3.54.18+PM.png" height="392" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Precipitation view of an island.</td></tr>
</tbody></table>
<br />
I implemented an auto-turn feature too. It's pretty neat to go the map and watch time go by at about 10 to 15 minutes per second. You can see clouds form and move and drop rain and dissipate. Cold rainy winters, brief dry spells, and warm summer days. It's always neat to try tweaking a variable or interaction and watch it actually work.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBNNPQVEKVNhxDd6JUQ70UsO3t-XS5tZChdpT0WXIcQfFA2TPDjYq2pP_HU7RivmapmUGe9MJ38ImfWcDBH556ilA1S6FshoKPwBYLD2EQ_C2o1OyiKCheVhk7uJ4uFG_43_WI7ZCHYVU/s1600/Screen+Shot+2014-12-14+at+3.29.40+PM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBNNPQVEKVNhxDd6JUQ70UsO3t-XS5tZChdpT0WXIcQfFA2TPDjYq2pP_HU7RivmapmUGe9MJ38ImfWcDBH556ilA1S6FshoKPwBYLD2EQ_C2o1OyiKCheVhk7uJ4uFG_43_WI7ZCHYVU/s1600/Screen+Shot+2014-12-14+at+3.29.40+PM.png" height="392" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px;">Walking through the hills during the most extreme downpour I saw.</td></tr>
</tbody></table>
I'll skip the implementation details but share some funny bugs from when I was trying different ideas:<br />
<br />
<ul>
<li>I tried making the temperature, clouds, and precipitation flow like in a fluid simulator. Nothing fancy, just a super simplified <a href="http://en.wikipedia.org/wiki/Navier%E2%80%93Stokes_equations">Navier Stokes</a> thing that never quite worked. The island was soon covered in a freezing uniform cloud that was always snowing. Except the tops of the highest mountains, they were a comfortable temperature.</li>
<li>I tried implementing clouds as particles that would be deflected by high elevations. The first attempt caused them to bounce off mountains like beach balls and scatter everywhere. I was able to tweak it so that didn't happen and added wind that would nudge them back to their original direction but it wasn't very interesting.</li>
<li>I tried making temperature affect cloud formation and have clouds affect temperature. I soon had areas with 2000000% cloudiness and over 1000 degree heat.</li>
</ul>
<br />
<br />
<b>Geology. </b>The land generation has been tweaked quite a bit. Also, there's a few different types of land that are somewhat determined by climate. No lakes or rivers yet though.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihG1kM6C9qAfnMBUj1lcLYxJyDHVTg5DwQUlOAUpEI8Z_jkCQRgdKdT_JgsyWosyBh3v5nYJ5jOr47gwiAsDfwCwFfn9vJdwlX_wafig_qY3hTuGvknJhoRZokJqt0V2AAmB7qMf3sslc/s1600/Screen+Shot+2014-12-14+at+4.08.51+PM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihG1kM6C9qAfnMBUj1lcLYxJyDHVTg5DwQUlOAUpEI8Z_jkCQRgdKdT_JgsyWosyBh3v5nYJ5jOr47gwiAsDfwCwFfn9vJdwlX_wafig_qY3hTuGvknJhoRZokJqt0V2AAmB7qMf3sslc/s1600/Screen+Shot+2014-12-14+at+4.08.51+PM.png" height="392" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A transition between dirt to the southwest and grass to the northeast. The grassy area probably gets more rainfall.</td></tr>
</tbody></table>
<br />
<hr />
<br />
Thinking of all the different ways to model weather has ben fun despite all the dead ends I ran into but I'm really looking to this upcoming week and adding some randomized plant life.Trystanhttp://www.blogger.com/profile/15653418292042541807noreply@blogger.com8tag:blogger.com,1999:blog-9121642240025958832.post-49365203689165651402014-12-07T09:58:00.001-08:002014-12-07T13:25:14.384-08:00Beginnings of worldgen (with pics) and spinoff projectsI got some basic worldgen done this week. Just creating a bare island and walking around on it but that's not bad for one week starting from scratch with a language I'm still learning.<br />
<br />
<hr />
<br />
Building the island's elevation uses a blend of a few different techniques:<br />
<br />
First, create a heightmap by throwing down a bunch of sorta-centered blobs with a random height and radius. A percentage of the blobs will have negative height and reduce the elevation. Keep throwing blobs until you have enough land. I think this has interesting and island-like coastlines with and good variation of height. It can be weirdly mesmerizing too.<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNkTohCdF5Fw4FhPHYE0XD7f3SqSVngdIzdkBPdNC7kS053cJEUtjxX_2e-02BZ062wFD2ulUOV4UjKs0SoZ3_FBx78F8Kd_U-DSBu5bqiGQTwWKfK4zsfAPGDw4BSxyfQZplIvlYJACM/s1600/blob-map-72x72.png" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNkTohCdF5Fw4FhPHYE0XD7f3SqSVngdIzdkBPdNC7kS053cJEUtjxX_2e-02BZ062wFD2ulUOV4UjKs0SoZ3_FBx78F8Kd_U-DSBu5bqiGQTwWKfK4zsfAPGDw4BSxyfQZplIvlYJACM/s200/blob-map-72x72.png" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8u0uVgv7K4yCnz-y664mVFVuyOTc2Dtu_bqleuqbSbqyKU1KYMjEhhYdMd22DDb_c3z3d9InyIjtnaEL7Y8g-Lb3NoEwjgPsJbsARR-WyBZz-ZsyjJW7KhxOwd1W9Dn1fFFmBOLa6qTM/s1600/blob-map-72x72.png" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8u0uVgv7K4yCnz-y664mVFVuyOTc2Dtu_bqleuqbSbqyKU1KYMjEhhYdMd22DDb_c3z3d9InyIjtnaEL7Y8g-Lb3NoEwjgPsJbsARR-WyBZz-ZsyjJW7KhxOwd1W9Dn1fFFmBOLa6qTM/s200/blob-map-72x72.png" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNoK1c_ggTNl8-aNlXAGeh8jhkY3MalEMvXpSMcZH6cjIKOyD68Ks-c6wTVPg4CTvI_I-UT3enxKivsSHKAXPcBJ7Fyez9qMPO6tCbDKWmLRTKQpRNwFrYahjGBEkALkPRdcTmLlCOkro/s1600/blob-map-72x72.png" imageanchor="1" style="margin-bottom: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNoK1c_ggTNl8-aNlXAGeh8jhkY3MalEMvXpSMcZH6cjIKOyD68Ks-c6wTVPg4CTvI_I-UT3enxKivsSHKAXPcBJ7Fyez9qMPO6tCbDKWmLRTKQpRNwFrYahjGBEkALkPRdcTmLlCOkro/s1600/blob-map-72x72.png" height="200" width="200" /></a><br />
<br />
Using the first heightmap, create a second heightmap based on the distance from the water. I think this looks neat on it's own and when there's jagged coastlines it reminds me of what real mountain ranges look like from above.<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieuQYYH3Ds3EKBk1wF_cA1UTQZqcHhRPNtZvRXfbBPArvp1hw7DOeVepkPVik8Pq-IjsWzwXH92ofMD0d2s7D5hxyeMWZTkFpt_LyiUSSA4yMsqNgKBkzGLnOJcATKMsu0H2s-LFbcNWc/s1600/distance-map-72x72.png" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieuQYYH3Ds3EKBk1wF_cA1UTQZqcHhRPNtZvRXfbBPArvp1hw7DOeVepkPVik8Pq-IjsWzwXH92ofMD0d2s7D5hxyeMWZTkFpt_LyiUSSA4yMsqNgKBkzGLnOJcATKMsu0H2s-LFbcNWc/s200/distance-map-72x72.png" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNuOyz3hh87xnVnP4O2PwXoHaPs-c17sZlqPObWg-Yn68-saTv1UFfkVuKlbzEM69AiOR8YP4sdNQd1oFXFkvg6yzEcO9ZCqbaj7yxCqu2XQ07A8iZa2qxbSmx2rKrOcCrJszZ7UrFhgA/s1600/distance-map-72x72.png" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNuOyz3hh87xnVnP4O2PwXoHaPs-c17sZlqPObWg-Yn68-saTv1UFfkVuKlbzEM69AiOR8YP4sdNQd1oFXFkvg6yzEcO9ZCqbaj7yxCqu2XQ07A8iZa2qxbSmx2rKrOcCrJszZ7UrFhgA/s200/distance-map-72x72.png" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIvnVzFuOXbg9tO7nkttySha5D5bY03BUGzSY0gxOliLmo__aThrQMJKO2DwilrKg2TEsk1TzZeRSvvYeaibuqk1qSFk45t3S01v873KDne2WgYU39NdeetktfdwXp06q0IWCn3Afo7Vk/s1600/distance-map-72x72.png" imageanchor="1" style="margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIvnVzFuOXbg9tO7nkttySha5D5bY03BUGzSY0gxOliLmo__aThrQMJKO2DwilrKg2TEsk1TzZeRSvvYeaibuqk1qSFk45t3S01v873KDne2WgYU39NdeetktfdwXp06q0IWCn3Afo7Vk/s1600/distance-map-72x72.png" height="200" width="200" /></a>
<br />
<br />
Using the first heightmap again, create a third heightmap based on simplex noise. Water has zero height and everything else is a noise lookup.<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiv3ESk57lyFoSxWWiYOLJsTESbDK-CnDgnuA50wKeKqyr5wmsYR7MgFYmbmXP-092f8UmJmSvHVbAvATjDlkP-0jS3AwqHjpokH8yNi4y0-bEFk80FrVXtYQ6ImrlKQCNp7LpKvHg2hTA/s1600/noise-map-72x72.png" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiv3ESk57lyFoSxWWiYOLJsTESbDK-CnDgnuA50wKeKqyr5wmsYR7MgFYmbmXP-092f8UmJmSvHVbAvATjDlkP-0jS3AwqHjpokH8yNi4y0-bEFk80FrVXtYQ6ImrlKQCNp7LpKvHg2hTA/s200/noise-map-72x72.png" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipiRu6sQ9lurUfJvO9XPyii94vLxY1Mtvwdb4WB20PJZVmuyD41Iuz6xWcIFr5FHngx1MgxeeQ-jbqIahMRpgC9RfwdDeaRWfviKBxkvssC4Wj_nO-NMm37p6SlobwrqIQvtLRWDngbgE/s1600/noise-map-72x72.png" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipiRu6sQ9lurUfJvO9XPyii94vLxY1Mtvwdb4WB20PJZVmuyD41Iuz6xWcIFr5FHngx1MgxeeQ-jbqIahMRpgC9RfwdDeaRWfviKBxkvssC4Wj_nO-NMm37p6SlobwrqIQvtLRWDngbgE/s200/noise-map-72x72.png" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJAhX2tjVcqEGCR4topZzwZOo2R-LGK-b410gqkjUT0LXCa0urnQp6lpvQS855_m16GFkHKyqGOE8-y4grnFpdEfs-xlMwIK5DpzDMFvtpqGXAlJ1GTzgp-3xU2bEQtQteaSspl8iBX4w/s1600/noise-map-72x72.png" imageanchor="1" style="margin-bottom: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJAhX2tjVcqEGCR4topZzwZOo2R-LGK-b410gqkjUT0LXCa0urnQp6lpvQS855_m16GFkHKyqGOE8-y4grnFpdEfs-xlMwIK5DpzDMFvtpqGXAlJ1GTzgp-3xU2bEQtQteaSspl8iBX4w/s1600/noise-map-72x72.png" height="200" width="200" /></a><br />
<br />
Once you have all three heightmaps, multiply each by a different weight and add them together form a final height map. By changing the multipliers for each, you can adjust the overall look to get the best of each map with few downsides.<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiA1Vj19wW2uF7aX5WzqVWG5Iv5Ui48LugUYo5eaZMQ9S4FEgo0eMXGiEcDW9XqTWm472aGqWB086jvMO4bkql9bNUQbBeoEly_vkPNtbOL-hvmPgb4y_B9BMs0VwqRouEHsPkGLP9fzq4/s1600/combined-map-72x72.png" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiA1Vj19wW2uF7aX5WzqVWG5Iv5Ui48LugUYo5eaZMQ9S4FEgo0eMXGiEcDW9XqTWm472aGqWB086jvMO4bkql9bNUQbBeoEly_vkPNtbOL-hvmPgb4y_B9BMs0VwqRouEHsPkGLP9fzq4/s200/combined-map-72x72.png" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEic472MAb_CdL2QH8KVnjfSoPlclYw4-S4jF4d2yqiTaMZztAt3P8MyMzu1EQxoGYMHQ3_8MewLKkruMAXgVeoI5RBySSV5ub1I3IgYoufpioJuWe68Y3v4wNN_VEWurM6rqB2YvYB1Hcc/s1600/combined-map-72x72.png" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEic472MAb_CdL2QH8KVnjfSoPlclYw4-S4jF4d2yqiTaMZztAt3P8MyMzu1EQxoGYMHQ3_8MewLKkruMAXgVeoI5RBySSV5ub1I3IgYoufpioJuWe68Y3v4wNN_VEWurM6rqB2YvYB1Hcc/s200/combined-map-72x72.png" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsAdFb4-cuer_pbzVxvN_VFBXIa26Y5UstOxrEMZPeWwLVSfDQ9PWarC6ioItLLPKiznN2FCFVPboBjwSE4jifXN3lgDF1ICNUt895hQBkuYqUWrweo4b3AESu9LjVMLd-E6STGpcRjfk/s1600/combined-map-72x72.png" imageanchor="1" style="margin-bottom: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsAdFb4-cuer_pbzVxvN_VFBXIa26Y5UstOxrEMZPeWwLVSfDQ9PWarC6ioItLLPKiznN2FCFVPboBjwSE4jifXN3lgDF1ICNUt895hQBkuYqUWrweo4b3AESu9LjVMLd-E6STGpcRjfk/s1600/combined-map-72x72.png" height="200" width="200" /></a><br />
<br />
Finally, I want the highest parts to really stand out above everything else so I do one last thing: cube each height (that is, set each height to height * height * height). This effectively pushes the lowest parts down and increases the contrast for the higher elevations.<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjV1qbYSOhWZ5n6ZIar3GQSM3rlNwuXlnxPaBgPdduGvBxMpy3V_1zH6tGzubIpmtsRmWl7wur1jPLJRHJ_TaRN3lO4elk_acxAr94S6IzPKEN1LZeh1xtpYex3vx4JcJmqcIe0HSUheg/s1600/fixed-map-72x72.png" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjV1qbYSOhWZ5n6ZIar3GQSM3rlNwuXlnxPaBgPdduGvBxMpy3V_1zH6tGzubIpmtsRmWl7wur1jPLJRHJ_TaRN3lO4elk_acxAr94S6IzPKEN1LZeh1xtpYex3vx4JcJmqcIe0HSUheg/s200/fixed-map-72x72.png" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVB2CgD5QVumNcptMICE5QQ6QmZVF_DPT2GULAGOiR5qjJGWAsOHdlcCAdEnoaju7iMJndEbR5Q5oMmYV4bxhKhcwDvNVMxiUDfuZjqyO1XLDrrbGeMAJB027-sXOF48PwwxWg71iZJfI/s1600/fixed-map-72x72.png" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVB2CgD5QVumNcptMICE5QQ6QmZVF_DPT2GULAGOiR5qjJGWAsOHdlcCAdEnoaju7iMJndEbR5Q5oMmYV4bxhKhcwDvNVMxiUDfuZjqyO1XLDrrbGeMAJB027-sXOF48PwwxWg71iZJfI/s200/fixed-map-72x72.png" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqY2EcY-80zqYBKU7acWk00sUx6R64KmRoMJvmfOD540cUTsoRzC2GDtLIeNc4wKhLliyJU7P887gIpuQsls8U0niSavVpxpksphoVAmB-xXSf7S6-Xhw3-ruFf3F_Lz3cADVEg1HrYl4/s1600/fixed-map-72x72.png" imageanchor="1" style="margin-bottom: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqY2EcY-80zqYBKU7acWk00sUx6R64KmRoMJvmfOD540cUTsoRzC2GDtLIeNc4wKhLliyJU7P887gIpuQsls8U0niSavVpxpksphoVAmB-xXSf7S6-Xhw3-ruFf3F_Lz3cADVEg1HrYl4/s1600/fixed-map-72x72.png" height="200" width="200" /></a><br />
<br />
That looks okay. I'm sure it will change more.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAin5F13vyYJF2cx3rQ6KcX9nY4dJ1HfgSYLsmWND7Ut9CMXCi6z_d-qmHqgqPyrlgLLZ48a53pZNp41W4J-AiFsX7g55OLlhBll9o6V81ipshwKq8dnjWvkVIrQ56PadsZ68cYc37skE/s1600/Screen+Shot+2014-12-07+at+7.54.39+AM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAin5F13vyYJF2cx3rQ6KcX9nY4dJ1HfgSYLsmWND7Ut9CMXCi6z_d-qmHqgqPyrlgLLZ48a53pZNp41W4J-AiFsX7g55OLlhBll9o6V81ipshwKq8dnjWvkVIrQ56PadsZ68cYc37skE/s400/Screen+Shot+2014-12-07+at+7.54.39+AM.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">An in-game map.</td></tr>
</tbody></table>
Each tile on the map represents "chunk" of 30x30 tiles for now. As you walk around, nearby chunks are instantiated as needed based on the overall map. It's blocky and not very exciting though.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLnhwh9EPjLvUl9cqwFJ6BQRjLyo24Pvb_wZh0_jKR-B829diKFagCZ0lEDlPvW0t89jy6SJ3dlQqKFmLSYFywFcR3HXkAbBa986qEiGS0ryeoy3dBSswvBYs5oiU8aTQrTE43bUQ7CKw/s1600/Screen+Shot+2014-12-07+at+7.55.37+AM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLnhwh9EPjLvUl9cqwFJ6BQRjLyo24Pvb_wZh0_jKR-B829diKFagCZ0lEDlPvW0t89jy6SJ3dlQqKFmLSYFywFcR3HXkAbBa986qEiGS0ryeoy3dBSswvBYs5oiU8aTQrTE43bUQ7CKw/s400/Screen+Shot+2014-12-07+at+7.55.37+AM.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Much higher elevation to the west, much lower elevation to the east. One level higher to the south and one level lower to the south east.</td></tr>
</tbody></table>
<br />
I think I can do something like a midpoint displacement algorithm to make it less blocky. Adding up-slopes and down-slopes at elevation boundaries and hiding the interior of the higher elevation should help make it look better too. That should keep me busy for a week.<br />
<br />
<b>Edit: </b>It took about three hours. The midpoint displacement wasn't working how I thought it would so I lerp the midpoints and add a bit of noise instead.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg31OCBUMhYoJIu4iQSR99U_S8ojHpEODot1GDEtltffENu-j2Hhx5JiLnTm_ggF4GH8fCkiTKJbrJ1kl3WMsZoE1cJz4Vhb15gad6oiqH9Mgz8x8ggHU9ja0LHhQgtE4V4lmtAc5VZipI/s1600/Screen+Shot+2014-12-07+at+1.21.58+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg31OCBUMhYoJIu4iQSR99U_S8ojHpEODot1GDEtltffENu-j2Hhx5JiLnTm_ggF4GH8fCkiTKJbrJ1kl3WMsZoE1cJz4Vhb15gad6oiqH9Mgz8x8ggHU9ja0LHhQgtE4V4lmtAc5VZipI/s1600/Screen+Shot+2014-12-07+at+1.21.58+PM.png" height="392" width="640" /></a></div>
<br />
<hr />
<br />
Doing all that was almost 350 lines of Clojure so I moved some functionality into separate open source libraries.<br />
<br />
<a href="https://github.com/trystan/super-simple-window">super-simple-window</a>: Java Swing windows can have a ton of callbacks and settings that need to be done in a specific order and I always forget how to do it right. This is one function that creates a JFrame with a Canvas that uses all the settings and callbacks you supply: title, width, height, on-render, on-key-press, etc. Even makes a timer if you supply an on-timer callback.<br />
<br />
<a href="https://github.com/trystan/terminal-render">render-terminal</a>: Render terminal-like data to a Java Swing Graphics object. Call render with a map of points to character data. Does a bunch of caching to keep things fast. Supports 9x16, 10x10, and a 12x12 font so far but it's easy to extend.Trystanhttp://www.blogger.com/profile/15653418292042541807noreply@blogger.com30tag:blogger.com,1999:blog-9121642240025958832.post-13448413575254024332014-12-01T21:58:00.000-08:002014-12-01T21:58:19.045-08:00Announcing an unnamed ambitious roguelikeI've had a few ideas bumping around in my head for long enough that I decided to make a real roguelike. A big roguelike. A wilderness survival, city building, and dungeon crawling roguelike.<br />
<br />
<b>Wilderness survival.</b> Largely influenced by Robinson Crusoe by Daniel Defoe, The Mysterious Island by Jules Verne, and the potion identification aspects of other roguelikes. You begin alone on an island with randomly generated regions, plants, and animals. You have to find or build shelter, find safe drinking water, find plants and animals that are safe to eat, and explore the dangerous island.<br />
<br />
<b>City building.</b> Largely inspired by the The Sims games, the tougher Dwarf Fortress locations, the Dungeon Keeper games, and various history books such as The Outline Of History by H. G. Wells, A Short History of Nearly Everything by Bill Bryson, and the Foundation Series by Isaac Asimov. Eventually you find other people on the island and form a small town. You have a lot of influence but everyone goes about their business of farming, crafting, building, trading, exploring, adventuring, having families, and slowly unlocking new discoveries. But what happens when your town grows large and diverse enough for powerful families, ideologies, and factions to form?<br />
<br />
<b>Dungeon crawling.</b> Largely inspired by Sil, Brogue, DCSS, Nethack and other roguelikes. The island has many caves, ruins, dungeons, and fortresses. Use cool items, abilities, and allies to explore and plunder them. Of course, other adventurers are trying to do the same and some dungeons may send their inhabitants out to raid the overworld.<br />
<br />
<br />
I know thats just a bunch of words with no details or actual gameplay yet, but I'm excited to start a new project and can't wait to get something playable. I made a new git repo today and I hope to have the first playable version out sometime this month.Trystanhttp://www.blogger.com/profile/15653418292042541807noreply@blogger.com5tag:blogger.com,1999:blog-9121642240025958832.post-68338990089144743762013-10-04T11:16:00.000-07:002013-10-04T11:16:04.596-07:00Worldgen and dungeon variations in Pugnacious Wizards 2<br />
I want to share the basic world generation algorithm used in Pugnacious Wizards 2 and some things I did to add as much replayability, variety, and interest to the world generation. Hopefully you can try some of these ideas in your roguelikes.<br />
<br />
In case you haven't seen it yet, the game takes place in a densely packed single level castle that's made of a 9 by 9 grid of 7 by 7 rooms. Here's an example of what the entire game looks like on the first turn without FOV applied:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhywMi7NeoR_nHZSX7hsuwjI0HnNmqgtsrGIpYRJjnsumoGRs1nat0U7CTcvVtGdsLlrRPkrUMxd4FurkBJDauFXWWbs7aApTKz49ub7FFkC3Sf62_Ci6uu6F4t0RIQQJOggrRi7IMBrug/s1600/PW2_castle.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhywMi7NeoR_nHZSX7hsuwjI0HnNmqgtsrGIpYRJjnsumoGRs1nat0U7CTcvVtGdsLlrRPkrUMxd4FurkBJDauFXWWbs7aApTKz49ub7FFkC3Sf62_Ci6uu6F4t0RIQQJOggrRi7IMBrug/s1600/PW2_castle.png" /></a></div>
<br />
Here's the basic algorithm that Pugnacious Wizards 2 uses to create a level. It can be adapted to other roguelikes too:<br />
<br />
<ol>
<li><b>Start with a perfect maze</b>. A perfect maze is a maze with no loops - there's one and only one way from each room to each room. This means there's lots of choices since most rooms will have two or three doors that you can go through. This also means there's lots of dead ends. There's <a href="http://www.astrolog.org/labyrnth/algrithm.htm">a ton of great resources</a> on the internet about maze types, maze making algorithms, and maze solving algorithms. I don't think dead ends are fun so that's what the next step solves.</li>
<li><b>Add extra connections</b>. Decide how many dead ends you want to have and as long as there are more dead ends than that, connect a dead end to a random neighboring room. I choose to make each dungeon have up to 12 dead ends - each with it's own treasure. Three dead ends have amulets that you collect to win, six dead ends have a spell that you can pick up, and the remaining few dead ends have heart containers that will heal you.</li>
<li><b>Place themed rooms</b>. Now that all the rooms are connected, assign a random theme to each one and place them on the actual map. There's about a dozen themes: empty rooms, wall traps, floor traps, courtyard, treasure room, portal room, etc. Most rooms also have extra walls that follow a preset pattern and maybe a few randomly placed wall tiles. Trees are also added. This adds a bit more variability and tactical options. You can hide behind walls to avoid traps and burn trees to damage others or yourself. Room themes that include treasures, traps, guards, archers, or wizards will also place those at this time. Finally, each room has a very small percent of being a special version: a courtyard will be completely filled with trees, an empty room will be filled with skeletons, a trap room will have far more traps, etc.</li>
<li><b>Place regional themes</b>. Each treasure room with an amulet is guarded by a fire wizard, a poison wizard, or an ice wizard. That room and three rooms joined to it are rethemed with the appropriate element: all the traps are changed to that element and visible floor traps are placed in the corners of each room. Also the element is applied to each tile; water gets frozen or poisoned, grass and trees get burnt or poisoned, etc. This means you can tell when you're close to the amulets and is sort of like a mini-level in the dungeon. Most games have ice levels or fire levels and this is one way to get that same feeling in a single dungeon. In the above example picture, you can see how the poison region near the center of the castle has greenish poisoned water in one room and the fire region in the upper right of the castle has grass that's on fire. If there were any towers or traps then they would also be themed.</li>
<li><b>Place extra stuff</b>. Additional gold, blood, bone piles, and see-through wall tiles are added at random.</li>
</ol>
<br />
<div>
So that's the basic algorithm. A perfect maze with extra connections, treasures in the dead ends, themed rooms, themed areas, and extra loot.<br />
<br />
But that's not all that happens. The real variety comes from tweaking the worldgen algorithm itself.<br />
<br />
<b>Tweak the variables</b>. These variables include what percent of grass tiles are trees, what percent of walls that have see-through tiles added, what percent of doors are unburnable stone doors, how many extra room connections are added, how much total gold there is, and a few other things. In the above example picture, you can see how trees are common in the courtyards and as decorations in other rooms.<br />
<br />
<b>Tweak the lists</b>. It starts with a list of every room theme: 12 or so in total. Then a few are removed at random - they won't show up in this game. Then a few are chosen from the remaining at random and added to the list again - these themes will show up more often than others. This small difference means you can play a few games before seeing each theme. It can also change the feel quite a bit. A dungeon with lots of portals plays differently than one with no portals and a dungeon with lots of anti-magic rooms plays differently than one with lots of trap rooms or lots of creature rooms. In the above example picture, you can see how there are plenty of archer barracks but no guard barracks: they must have been removed from the list of room themes.<br />
<br />
<b>Apply explicit variations</b>. There's a list of 30 or so variations. Two, three, or four are picked at random and applied to the map and added to the subtitle. Some variations just make one room theme far more common by adding it to the list of themes 9 times, some will change the stats of archers or guards, some change how much damage is done by fire, ice, poison, arrows, or melee, and some have other small effects like changing the prices of spells, how large explosions are, etc. A game where skeletons regenerate in only a few turns is very different than a game where fire traps are far more common and do double damage. In the above example picture, you can see how archer barracks, which have an "a" pattern on the floor, and portal rooms, which have a glowing block in the center, are far more common than other rooms. These variations also affect the subtitle.</div>
Trystanhttp://www.blogger.com/profile/15653418292042541807noreply@blogger.com6tag:blogger.com,1999:blog-9121642240025958832.post-30446768498895876862013-09-30T10:57:00.001-07:002013-09-30T12:44:24.316-07:00Pugnacious Wizards 2 retrospectiveI did it! I spent six weeks on remaking and improving my 7DRL Pugnacious Wizards. Time for a retrospective.<br />
<br />
<br />
<b>What went well.</b><br />
<ul>
<li>I finished. I picked ambitious goals, a deadline of the 2014 ARRP, and actually did it. I've started a lot of programming projects but finished few of them - it feels good to finish a project.</li>
<li>Cleaner magic code. The code for the magic spells is much cleaner than the 7DRL version.</li>
</ul>
<br />
<b>What went poorly.</b><br />
<ul>
<li>Screen size. It's supposed to be played 800x640 like at the website but if you download it and play it in the standalone Flash Player, you can resize it and get some ugliness. I remember that happening with the 7DRL version, but I guess I forgot to display a warning if it is at an unexpected resolution.</li>
<li>Separating objects from their display. I tried to really separate the objects and the display of the objects. The tiles, items, creatures, effects, etc don't say what symbols or colors they display with. I figured it was ok for them to know that but I wanted to try something different and see if it's really cleaner to make the objects not know anything about their display. For PW2, the WorldDisplay class has a few giant switches and a bunch of if statements to determine what the background color, foreground color, and glyphs for each object in the game is. It's a mess but I tested a hypothesis and learned my lesson: don't go overboard with separating the objects and their display.</li>
</ul>
<b><br /></b>
<b>What should be done differently next time.</b><br />
<ul>
<li>There were a few weeks where I was throwin' out features every other day and times where I'd go a few weeks with only one update. Maybe having monthly goals would help smooth that out. I don't know if that was a real problem or not though.</li>
<li>Parameterizable tiles. I really pushed the Tile class to the extreme and it got ugly. The tiles are all single instances of things like light_floor, dark_floor, tower, ice_tower, fire_tower, etc. I made them all the same instance for performance reasons and because that's what I'm used to but I'm not sure if it's worth it. Maybe I should have made each tile a full fledged object oriented parameterizable object instead of something like an enum.</li>
<li>Feedback. I got some feedback but most updates didn't get any at all. I've been posting to the roguelike development forums and trying to get more visibility. I'll contribute more to other's projects and maybe that will help direct some eyes and feedback to my next project. Game Hunter did do <a href="http://www.youtube.com/watch?v=VOBCScsew54">an amazing LP</a> but that was after the final version.</li>
</ul>
<div>
<br />
<br /></div>
Trystanhttp://www.blogger.com/profile/15653418292042541807noreply@blogger.com3tag:blogger.com,1999:blog-9121642240025958832.post-87197034605945549872013-09-22T12:57:00.000-07:002013-09-22T13:26:36.796-07:00Pugnacious Wizards 2: version 1.0<div id="altContent" style='width:800px;height:640px'>
<a href="http://www.adobe.com/go/getflashplayer">Get Adobe Flash player</a>
</div>
<p>
Version 1.0 mostly adds variations. Each game you play will have 2, 3, or 4 "variations" added. Variations will tweak how the castle is made; how much treasure, enemies, or other things there are; your enemy stats; or a couple other things. You can tell which variations are in play by looking at the subtitle at the top of the screen.
</p>
<p>
This is the last planned release of Pugnacious Wizards 2. I'm done with it. I didn't add all the spells I could think of - and there's more that could be done with it - but I think it's good enough for me to move on. I tried some new things in the code as well as some new ideas about magic and traps and worldgen. It's a nice little game and I'm pretty happy with it. My next post will be a retrospective where I'll go into that further.
</p>
<p>
As always, any feedback is welcome.
</p>
<p><a href='https://github.com/trystan/PugnaciousWizards2'>github source</a></p>
<p><a href='https://sites.google.com/site/trystansprojects/PugnaciousWizards2_10.swf'>download swf</a></p>
<script src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js">
</script>
<script>
var flashvars = {
};
var params = {
menu: "false",
scale: "noScale",
allowFullscreen: "true",
allowScriptAccess: "always",
bgcolor: "",
wmode: "direct" // can cause issues with FP settings & webcam
};
var attributes = {
id:"Roguelike"
};
swfobject.embedSWF(
"https://sites.google.com/site/trystansprojects/PugnaciousWizards2_10.swf",
"altContent", "800px", "640px", "10.0.0",
"https://sites.google.com/site/trystansprojects/expressInstall.swf",
flashvars, params, attributes);
</script>Trystanhttp://www.blogger.com/profile/15653418292042541807noreply@blogger.com4tag:blogger.com,1999:blog-9121642240025958832.post-57839167678496514862013-09-09T15:52:00.000-07:002013-09-22T13:24:13.814-07:00Pugnacious Wizards 2, version 0.8<div id="altContent" style='width:800px;height:640px'>
<a href="http://www.adobe.com/go/getflashplayer">Get Adobe Flash player</a>
</div>
<p>
Version 0.8 adds mouse support as well as several small tweaks and a few new spells.
</p>
<p>
As always, any feedback is welcome.
</p>
<p><a href='https://github.com/trystan/PugnaciousWizards2'>github source</a></p>
<p><a href='https://sites.google.com/site/trystansprojects/PugnaciousWizards2_8.swf'>download swf</a></p>
<p><b>update</b> the latest version is at <a href="http://trystans.blogspot.com/2013/09/pugnacious-wizards-2-version-10.html">http://trystans.blogspot.com/2013/09/pugnacious-wizards-2-version-10.html</a></p>
<script src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js">
</script>
<script>
var flashvars = {
};
var params = {
menu: "false",
scale: "noScale",
allowFullscreen: "true",
allowScriptAccess: "always",
bgcolor: "",
wmode: "direct" // can cause issues with FP settings & webcam
};
var attributes = {
id:"Roguelike"
};
swfobject.embedSWF(
"https://sites.google.com/site/trystansprojects/PugnaciousWizards2_8.swf",
"altContent", "800px", "640px", "10.0.0",
"https://sites.google.com/site/trystansprojects/expressInstall.swf",
flashvars, params, attributes);
</script>Trystanhttp://www.blogger.com/profile/15653418292042541807noreply@blogger.com5tag:blogger.com,1999:blog-9121642240025958832.post-40200531054855719802013-08-06T22:04:00.003-07:002013-09-22T13:23:58.466-07:00Pugnacious Wizards 2, version 0.7<div id="altContent" style='width:800px;height:640px'>
<a href="http://www.adobe.com/go/getflashplayer">Get Adobe Flash player</a>
</div>
<p>
Version 0.7 doesn't add any major features but manages to tweak so many things so much that it deserves a release of its own. I added lots of little performance improvements, new poison traps, some new dungeon architecture, a few new spells, new dungeon themed areas, and several tweaks to the interface, spells, effects, and ai.
</p>
<p>
As always, any feedback is welcome.
</p>
<p><a href='https://github.com/trystan/PugnaciousWizards2'>github source</a></p>
<p><a href='https://sites.google.com/site/trystansprojects/PugnaciousWizards2_7.swf'>download swf</a></p>
<p><b>update</b> the latest version is at <a href="http://trystans.blogspot.com/2013/09/pugnacious-wizards-2-version-10.html">http://trystans.blogspot.com/2013/09/pugnacious-wizards-2-version-10.html</a></p>
<script src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js">
</script>
<script>
var flashvars = {
};
var params = {
menu: "false",
scale: "noScale",
allowFullscreen: "true",
allowScriptAccess: "always",
bgcolor: "",
wmode: "direct" // can cause issues with FP settings & webcam
};
var attributes = {
id:"Roguelike"
};
swfobject.embedSWF(
"https://sites.google.com/site/trystansprojects/PugnaciousWizards2_7.swf",
"altContent", "800px", "640px", "10.0.0",
"https://sites.google.com/site/trystansprojects/expressInstall.swf",
flashvars, params, attributes);
</script>Trystanhttp://www.blogger.com/profile/15653418292042541807noreply@blogger.com3tag:blogger.com,1999:blog-9121642240025958832.post-37093160812559999122013-08-02T12:51:00.001-07:002013-09-22T13:23:48.052-07:00Pugnacious Wizards 2, version 0.6<div id="altContent" style='width:800px;height:640px'>
<a href="http://www.adobe.com/go/getflashplayer">Get Adobe Flash player</a>
</div>
<p>
Version 0.6 adds several new spells, enemy wizards, gold to pickup and spend, and performance improvements.
</p>
<p>
As always, any feedback is welcome.
</p>
<p><a href='https://github.com/trystan/PugnaciousWizards2'>github source</a></p>
<p><a href='https://sites.google.com/site/trystansprojects/PugnaciousWizards2_6.swf'>download swf</a></p>
<p><b>update</b> the latest version is at <a href="http://trystans.blogspot.com/2013/09/pugnacious-wizards-2-version-10.html">http://trystans.blogspot.com/2013/09/pugnacious-wizards-2-version-10.html</a></p>
<script src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js">
</script>
<script>
var flashvars = {
};
var params = {
menu: "false",
scale: "noScale",
allowFullscreen: "true",
allowScriptAccess: "always",
bgcolor: "",
wmode: "direct" // can cause issues with FP settings & webcam
};
var attributes = {
id:"Roguelike"
};
swfobject.embedSWF(
"https://sites.google.com/site/trystansprojects/PugnaciousWizards2_6.swf",
"altContent", "800px", "640px", "10.0.0",
"https://sites.google.com/site/trystansprojects/expressInstall.swf",
flashvars, params, attributes);
</script>Trystanhttp://www.blogger.com/profile/15653418292042541807noreply@blogger.com12tag:blogger.com,1999:blog-9121642240025958832.post-53886370521242366612013-06-25T22:39:00.000-07:002013-09-22T13:23:38.623-07:00Pugnacious Wizards 2, version 0.4 (now worth playing!)<div id="altContent" style='width:800px;height:640px'>
<a href="http://www.adobe.com/go/getflashplayer">Get Adobe Flash player</a>
</div>
<p>
Version 0.4 adds several new spells - 9 total. There's a bit of a slowdown sometimes, but I'm looking into that.
</p>
<p>
This is mostly what I want. The next few updates will probably just add content (like new spells) with very few major changes.
</p>
<p>
As always, any feedback is welcome.
</p>
<p><a href='https://github.com/trystan/PugnaciousWizards2'>github source</a></p>
<p><a href='https://sites.google.com/site/trystansprojects/PugnaciousWizards2_4.swf'>download swf</a></p>
<p><b>update</b> the latest version is at <a href="http://trystans.blogspot.com/2013/09/pugnacious-wizards-2-version-10.html">http://trystans.blogspot.com/2013/09/pugnacious-wizards-2-version-10.html</a></p>
<script src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js">
</script>
<script>
var flashvars = {
};
var params = {
menu: "false",
scale: "noScale",
allowFullscreen: "true",
allowScriptAccess: "always",
bgcolor: "",
wmode: "direct" // can cause issues with FP settings & webcam
};
var attributes = {
id:"Roguelike"
};
swfobject.embedSWF(
"https://sites.google.com/site/trystansprojects/PugnaciousWizards2_4.swf",
"altContent", "800px", "640px", "10.0.0",
"https://sites.google.com/site/trystansprojects/expressInstall.swf",
flashvars, params, attributes);
</script>Trystanhttp://www.blogger.com/profile/15653418292042541807noreply@blogger.com2tag:blogger.com,1999:blog-9121642240025958832.post-60334093122220780992013-06-18T20:49:00.000-07:002013-06-18T20:49:36.974-07:00TDDing yourself into a corner<p>I've been playing around with Scala lately and while doing the Roman Numeral kata, I ended up with this.</p>
<code><pre>
def numeral(i:Int):String = {
if (i == 0) return ""
if (i % 1000 <= 900) return numeral(i-900) + "CM"
if (i % 1000 == 0) return numeral(i-1000) + "M"
if (i % 500 <= 400) return numeral(i-400) + "CD"
if (i % 500 == 0) return numeral(i-500) + "D"
if (i % 100 <= 90) return numeral(i-90) + "XC"
if (i % 100 == 0) return numeral(i-100) + "C"
if (i % 50 <= 40) return numeral(i-40) + "XL"
if (i % 50 == 0) return numeral(i-50) + "L"
if (i % 10 == 9) return numeral(i-9) + "IX"
if (i % 10 == 0) return numeral(i-10) + "X"
if (i % 5 == 4) return numeral(i-4) + "IV"
if (i % 5 == 0) return numeral(i-5) + "V"
numeral(i-1) + "I"
}
</pre></code>
<p>I <a href="http://c2.com/xp/DoTheSimplestThingThatCouldPossiblyWork.html">did the simplest thing that possibly could work</a>, followed the <a href="http://agileinaflash.blogspot.com/2009/02/red-green-refactor.html">red/green/refactor</a> cycle, and I even followed <a href="http://blog.8thlight.com/uncle-bob/2013/05/27/TheTransformationPriorityPremise.html">The Transformation Priority Premise</a>. There's better ways of doing this, but I think I'm stuck in a local maximum and I'm not sure how to refactor my way out of it. Using a lookup table is an obvious improvement (such as <code>List((1,"I"),(5,"V"),(10,"X") ...</code>) but those funky comparisons make how to get there non-obvious. TDD doesn't seem to point me in one direction or another. I do believe that Test Driven Development often leads to clean and well factored code so this is an interesting case. TDD lead me down each step I took to get here and it's not leading me anywhere from here. So maybe this is the simplest way to write this?</p>Trystanhttp://www.blogger.com/profile/15653418292042541807noreply@blogger.com3tag:blogger.com,1999:blog-9121642240025958832.post-37697955963852561512013-06-16T14:09:00.000-07:002013-09-22T13:23:26.241-07:00Pugnacious Wizards 2, version 0.3<div id="altContent" style='width:800px;height:640px'>
<a href="http://www.adobe.com/go/getflashplayer">Get Adobe Flash player</a>
</div>
<p>
Version 0.3 mostly adds help. There's a help screen, an examine screen, and help popups. There's also a few new room themes, but nothing much.
</p>
<p>
The next version will add several new spells and will — I think — be the first version worth actually playing.
</p>
<p>
As always, any feedback is welcome.
</p>
<p><a href='https://github.com/trystan/PugnaciousWizards2'>github source</a></p>
<p><a href='https://sites.google.com/site/trystansprojects/PugnaciousWizards2_3.swf'>download swf</a></p>
<p><b>update</b> the latest version is at <a href="http://trystans.blogspot.com/2013/09/pugnacious-wizards-2-version-10.html">http://trystans.blogspot.com/2013/09/pugnacious-wizards-2-version-10.html</a></p>
<script src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js">
</script>
<script>
var flashvars = {
};
var params = {
menu: "false",
scale: "noScale",
allowFullscreen: "true",
allowScriptAccess: "always",
bgcolor: "",
wmode: "direct" // can cause issues with FP settings & webcam
};
var attributes = {
id:"Roguelike"
};
swfobject.embedSWF(
"https://sites.google.com/site/trystansprojects/PugnaciousWizards2_3.swf",
"altContent", "800px", "640px", "10.0.0",
"https://sites.google.com/site/trystansprojects/expressInstall.swf",
flashvars, params, attributes);
</script>Trystanhttp://www.blogger.com/profile/15653418292042541807noreply@blogger.com1tag:blogger.com,1999:blog-9121642240025958832.post-32455368788823601612013-06-10T18:00:00.001-07:002013-09-22T13:23:16.245-07:00Pugnacious Wizards 2, version 0.2<div id="altContent" style='width:800px;height:640px'>
<a href="http://www.adobe.com/go/getflashplayer">Get Adobe Flash player</a>
</div>
<p>
Version 0.2 adds guards, archers, new rooms, health pickups, better lighting and effects, and many tweaks. I can beat the game about half the time, which means it's too easy. It takes about 20 minutes to play. It's starting to feel like a real game even though it only has three spells.
</p>
<p>
As always, any feedback is welcome.
</p>
<p><a href='https://github.com/trystan/PugnaciousWizards2'>github source</a></p>
<p><a href='https://sites.google.com/site/trystansprojects/PugnaciousWizards2_2.swf'>download swf</a></p>
<p><b>update</b> the latest version is at <a href="http://trystans.blogspot.com/2013/09/pugnacious-wizards-2-version-10.html">http://trystans.blogspot.com/2013/09/pugnacious-wizards-2-version-10.html</a></p>
<script src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js">
</script>
<script>
var flashvars = {
};
var params = {
menu: "false",
scale: "noScale",
allowFullscreen: "true",
allowScriptAccess: "always",
bgcolor: "",
wmode: "direct" // can cause issues with FP settings & webcam
};
var attributes = {
id:"Roguelike"
};
swfobject.embedSWF(
"https://sites.google.com/site/trystansprojects/PugnaciousWizards2_2.swf",
"altContent", "800px", "640px", "10.0.0",
"https://sites.google.com/site/trystansprojects/expressInstall.swf",
flashvars, params, attributes);
</script>Trystanhttp://www.blogger.com/profile/15653418292042541807noreply@blogger.com0tag:blogger.com,1999:blog-9121642240025958832.post-14033795607152737892013-06-07T18:26:00.003-07:002013-09-22T12:57:57.566-07:00Pugnacious Wizards 2, version 0.1<div id="altContent" style='width:800px;height:640px'>
<a href="http://www.adobe.com/go/getflashplayer">Get Adobe Flash player</a>
</div>
<p>
I really enjoyed making and playing my 7DRL PugnaciousWizards. So I started from scratch and have made a new one. Or at least some of it. There's only three spells and a bunch of traps so far. There's no help, examine, or explanatory popups. No bad guys either.
</p>
<p>
As always, any feedback is welcome.
</p>
<p><a href='https://github.com/trystan/PugnaciousWizards2'>github source</a></p>
<p><a href='https://sites.google.com/site/trystansprojects/PugnaciousWizards2_1.swf'>download swf</a></p>
<p><b>update</b> the latest version is at <a href="http://trystans.blogspot.com/2013/09/pugnacious-wizards-2-version-10.html">http://trystans.blogspot.com/2013/09/pugnacious-wizards-2-version-10.html</a></p>
<script src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js">
</script>
<script>
var flashvars = {
};
var params = {
menu: "false",
scale: "noScale",
allowFullscreen: "true",
allowScriptAccess: "always",
bgcolor: "",
wmode: "direct" // can cause issues with FP settings & webcam
};
var attributes = {
id:"Roguelike"
};
swfobject.embedSWF(
"https://sites.google.com/site/trystansprojects/PugnaciousWizards2_1.swf",
"altContent", "800px", "640px", "10.0.0",
"https://sites.google.com/site/trystansprojects/expressInstall.swf",
flashvars, params, attributes);
</script>Trystanhttp://www.blogger.com/profile/15653418292042541807noreply@blogger.com0tag:blogger.com,1999:blog-9121642240025958832.post-89525856710192921562013-04-10T23:42:00.000-07:002013-04-10T23:42:08.193-07:00Pugnacious Wizards Retrospective<p>Pugnacious Wizards!</p>
<p>
Another year, another 7DRL. This year I tired to focus on more interesting traps and more interesting magic. When I could, I tried to include help for newbies and veteran players too. So what happened?
</p>
<p><b>What went well?</b>
<p>Traps. There's basically four traps. Each is different. Some are obvious (the arrow towers and rotating towers) while some aren't obvious (floor traps and wall arrows). Each can be used to hurt others once you figure out how to avoid them. Even though the floor traps were the most boring, it's possible to figure out the pattern for the room and use it to your advantage. So traps become a benefit rather than a detriment. Pretty cool I guess. I had ideas of moving spike balls, retracting bridges, and other wackyness. The basic idea is discovering patterns in your surroundings and using it to your advantage by avoiding the dangerous spots and tricking your enemies into the most dangerous spots. The gameplay is pretty good (I think) and the code is not too bad for a quick-n-dirty 7DRL. One interesting thing is that the World class has a list of functions it calls every turn. Many of the traps were implemented by telling the world to call some function each turn. That means that the items, tiles, and world didn't have to be changed in order to implement traps. Totally <a href="http://en.wikipedia.org/wiki/Open/closed_principle">OCP</a>. Totally rad.
</p>
<p>Interesting magic. This was the first time I really tried making a magic system. I hard coded a lot of things, then refactored to be more reusable. Even though I didn't get as many magic spells as I wanted, it worked. And there's a few emergent effects (freezing yourself when on fire, burning trees near enemies, etc). The code was <i>just barely</i> flexible enough for this 7DRL. I did manage to make use of the <a href="https://github.com/trystan/PugnaciousWizards/blob/master/src/delivery/Composite.as">Composite Pattern</a>.
</p>
<p>Simple enemies, no stats, no items. The focus is on magic and traps. That means the game really only needs a few enemies. A melee type, a ranged type, and possibly a magic using type. The skeletons are just there to force you to move on. The interesting magic means there's less need for stats and equipment. Although I've got ideas about that too....</p>
<p>
Help. I added an attract screen where the computer tries to run through the game. It's a good way to show the basics of what's going on. I also added a decent help screen, the ability to examine surroundings and current spells, as well as popups for the first time you see new things - although it <i>must</i> be dismissible for those who don't want to be bothered by it. I think that was a fantastic success. I also managed to make a game that required very few keys (WASD & 1-9) but also allowed different input styles (arrows,WASD,HJKLYUBN,1-9,mouse). None of those things make it a better roguelike, but it was important to me that it's easy to understand and play. That's also why I used ActionScript rather than Java like last year. The low barrier to entry is important.
</p>
<p><b>What didn't go well?</b></p>
<p>Magic. I didn't get as many spells and effects as I was hoping for. I was planning on having 27 spells total, 18 in each dungeon, and you can only pick up 9. I didn't get that many spells though. 12 total I think. I was also missing many effects that I wanted: push, stone skin, anti-stone, control others, and more. This was mostly due to not really figuring out how effects and such would work together. What I ended up with wasn't flexible enough for all that I wanted - which was quite ambitious. But it wasn't very well refactored. I think it was quickly accumulated <a href="http://c2.com/cgi/wiki?WardExplainsDebtMetaphor">Technical Debt</a> that slowed me down. Debt in the sense that I learned about making reusable magic code faster than I was refactoring the magic code.</p>
<p>AI. The AI for the intro screen hero and other wizards doesn't know how to best use every spell that's in the game. They can use most, but even then, it's not always the optimal move. That's ok, but some spells it flat out ignores. That's pretty lame. This was entirely due to how I implemented the magic. I should have thought this out better. Technical Debt strikes again.</p>
<p><b>What would I do differently next time?</b></p>
<p>Magic is tough. At least the style that I wanted. I really should have though about it more and have had a better idea of what was needed. I actually tried not to over think it. Maybe I under thought it.</p>
<p>Useless non-contet. Like many 7DRL challengers, I added a lot of useless content that wasn't related to may main focuses. There were probably two day's worth of work that were wasted on trying to make "interesting" rooms that weren't related to traps or magic. That was removed sense it only made the gameplay worse. It seems that I'm always reminding clients and coworkers to focus on what's important yet this time I made that same mistake. Sometimes human nature conspires against us.</p>Trystanhttp://www.blogger.com/profile/15653418292042541807noreply@blogger.com6tag:blogger.com,1999:blog-9121642240025958832.post-55373058141103746992013-03-16T19:53:00.003-07:002013-09-09T15:53:34.722-07:00Pugnacious Wizards day 7<h2>Success!</h2>
<p>I didn't have time to do much the last couple days but overall, I'm pretty happy with what I made.</p>
<div id="altContent" style='width:800px;height:640px'>
<a href="http://www.adobe.com/go/getflashplayer">Get Adobe Flash player</a>
</div>
<p>
I wanted to focus on magic spells that had multiple effects and traps that are more interesting than the standard "randomly take a trivial amount of damage" that most roguelikes have. I think I did both. Maybe not as much as I had hoped for, but I did both. I also wanted to explain more of the game with an intro that auto-palys and help popups. I think that worked very well.
</p>
<p>
As far as programming goes, I was able to get animations working - which I've never done before. I also tried putting much of the ai into spells so that the hero and wizards know how to cast them. The magic system wasn't as clean as I wanted, but I tried a few new things with that too. One of the coolest things I did was to make it so the world has a list of functions that it calls each turn. Since anything that has a reference to the world can add to that list, new functionality can be added without changing any existing code. Totally <a href="http://en.wikipedia.org/wiki/Open/closed_principle">OCP</a>. Much of the traps and magic used this.
</p>
<p>
As always, any feedback is welcome.
</p>
<p><a href='https://github.com/trystan/PugnaciousWizards'>github source</a></p>
<p><a href='https://sites.google.com/site/trystansprojects/PugnaciousWizards_7.swf'>download swf</a></p>
<p><b>Update:</b> I played it again after being away for a week and noticed that sometimes the FOV isn't calculated at the right time. I think I fixed it.</p>
<p><b>Update:</b> I started making a post-7DRL version with better traps, spells, and code. Give it a try at <a href="http://trystans.blogspot.com/2013/09/pugnacious-wizards-2-version-08.html">Pugnacious Wizards 2</a></p>
<script src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js">
</script>
<script>
var flashvars = {
};
var params = {
menu: "false",
scale: "noScale",
allowFullscreen: "true",
allowScriptAccess: "always",
bgcolor: "",
wmode: "direct" // can cause issues with FP settings & webcam
};
var attributes = {
id:"Roguelike"
};
swfobject.embedSWF(
"https://sites.google.com/site/trystansprojects/PugnaciousWizards_7.swf",
"altContent", "800px", "640px", "10.0.0",
"https://sites.google.com/site/trystansprojects/expressInstall.swf",
flashvars, params, attributes);
</script>Trystanhttp://www.blogger.com/profile/15653418292042541807noreply@blogger.com9tag:blogger.com,1999:blog-9121642240025958832.post-81355679589020720902013-03-14T23:20:00.000-07:002013-03-14T23:20:03.164-07:00Pugnacious Wizards day 5<p>Good progress today:</p>
<div id="altContent" style='width:800px;height:640px'>
<a href="http://www.adobe.com/go/getflashplayer">Get Adobe Flash player</a>
</div>
<p>
Fixed some minor animation and timing stuff as well as refactored magic and traps quite a bit. That meant I was able to improve magic and traps quite a bit.
</p>
<p>
As always, any feedback is welcome.
</p>
<p><a href='https://github.com/trystan/PugnaciousWizards'>github source</a></p>
<script src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js">
</script>
<script>
var flashvars = {
};
var params = {
menu: "false",
scale: "noScale",
allowFullscreen: "true",
allowScriptAccess: "always",
bgcolor: "",
wmode: "direct" // can cause issues with FP settings & webcam
};
var attributes = {
id:"Roguelike"
};
swfobject.embedSWF(
"https://sites.google.com/site/trystansprojects/PugnaciousWizards_5.swf",
"altContent", "800px", "640px", "10.0.0",
"https://sites.google.com/site/trystansprojects/expressInstall.swf",
flashvars, params, attributes);
</script>Trystanhttp://www.blogger.com/profile/15653418292042541807noreply@blogger.com1tag:blogger.com,1999:blog-9121642240025958832.post-56109315064735631272013-03-13T23:25:00.000-07:002013-03-13T23:25:06.753-07:00Pugnacious Wizards day 4<p>Very little progress today:</p>
<div id="altContent" style='width:800px;height:640px'>
<a href="http://www.adobe.com/go/getflashplayer">Get Adobe Flash player</a>
</div>
<p>
I had a social obligation which took up most of my evening. I did have some time to refactor the magic stuff. I'm still not entirely happy with how it's set up but now I can start doing more interesting things. Like the a new spell that teleports you then burns your surroundings or spell that freezes everyone near you then blinks you away. I'd like to come up with several spells that have three or four effects each. That's my goal at least.
</p>
<p>
Also tweaked the creature ai, removed some bad room themes, and other minor things.
</p>
<p>
As always, any feedback is welcome.
</p>
<p><a href='https://github.com/trystan/PugnaciousWizards'>github source</a></p>
<script src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js">
</script>
<script>
var flashvars = {
};
var params = {
menu: "false",
scale: "noScale",
allowFullscreen: "true",
allowScriptAccess: "always",
bgcolor: "",
wmode: "direct" // can cause issues with FP settings & webcam
};
var attributes = {
id:"Roguelike"
};
swfobject.embedSWF(
"https://sites.google.com/site/trystansprojects/PugnaciousWizards_4.swf",
"altContent", "800px", "640px", "10.0.0",
"https://sites.google.com/site/trystansprojects/expressInstall.swf",
flashvars, params, attributes);
</script>Trystanhttp://www.blogger.com/profile/15653418292042541807noreply@blogger.com5tag:blogger.com,1999:blog-9121642240025958832.post-35025484738138947362013-03-12T22:12:00.000-07:002013-03-12T22:14:32.606-07:00Pugnacious Wizards day 3<p>Some new content today but mostly polish:</p>
<div id="altContent" style='width:800px;height:640px'>
<a href="http://www.adobe.com/go/getflashplayer">Get Adobe Flash player</a>
</div>
<p>
I did add a few more room themes but most of my 5 or so hours was spent adding a help screen, an examine screen, and adding popups the first time you encounter major things like new rooms or enemies.
</p>
<p>
I won't have much time tomorrow but I'm going to focus on adding more interesting traps and puzzles over the next two days. That will leave Friday evening and Saturday to work on more interesting magic.
</p>
<p>
What do you think? Too confusing? Too simple? Too conventional? Let me know in the comments.
</p>
<p><a href='https://github.com/trystan/PugnaciousWizards'>github source</a></p>
<script src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js">
</script>
<script>
var flashvars = {
};
var params = {
menu: "false",
scale: "noScale",
allowFullscreen: "true",
allowScriptAccess: "always",
bgcolor: "",
wmode: "direct" // can cause issues with FP settings & webcam
};
var attributes = {
id:"Roguelike"
};
swfobject.embedSWF(
"https://sites.google.com/site/trystansprojects/PugnaciousWizards_3.swf",
"altContent", "800px", "640px", "10.0.0",
"https://sites.google.com/site/trystansprojects/expressInstall.swf",
flashvars, params, attributes);
</script>Trystanhttp://www.blogger.com/profile/15653418292042541807noreply@blogger.com2tag:blogger.com,1999:blog-9121642240025958832.post-50705519694674399412013-03-11T23:13:00.002-07:002013-03-11T23:13:49.177-07:00Pugnacious Wizards day 2<p>Some good progress today:</p>
<div id="altContent" style='width:800px;height:640px'>
<a href="http://www.adobe.com/go/getflashplayer">Get Adobe Flash player</a>
</div>
<p>
I added bloodstains and variation among grass and trees. I also got the hero to use magic against wizards who defend the amulet pieces. Finally, I was able to add a few room themes. There are 8 total, but two are randomly chosen to not appear and one is chosen to appear more often than others. The current themes are:
<ul>
<li>An "A" room that spawns archers</li>
<li>A "G" room that spawns guards</li>
<li>A room covered in blood</li>
<li>A room littered with piles of bones</li>
<li>A room with some pillars or remains of walls</li>
<li>A room that occasionally shoots arrows from one of the walls</li>
<li>A room shoots arrows in 8 directions from towers every turn you are in the room</li>
<li>A nice outdoor area</li>
</ul>
I plan on continuing with the room themes and adding more trap effects and triggers as well as some simple puzzles.
</p>
<hr/>
<p>
I almost forget! You can get the code from <a href='https://github.com/trystan/PugnaciousWizards'>https://github.com/trystan/PugnaciousWizards</a>. It's not my best code, and I've had to some odd workarounds since I'm using a few bits of old code to do new things, but it works and some of it is ok.
</p>
<script src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js">
</script>
<script>
var flashvars = {
};
var params = {
menu: "false",
scale: "noScale",
allowFullscreen: "true",
allowScriptAccess: "always",
bgcolor: "",
wmode: "direct" // can cause issues with FP settings & webcam
};
var attributes = {
id:"Roguelike"
};
swfobject.embedSWF(
"https://sites.google.com/site/trystansprojects/PugnaciousWizards_2.swf",
"altContent", "800px", "640px", "10.0.0",
"https://sites.google.com/site/trystansprojects/expressInstall.swf",
flashvars, params, attributes);
</script>Trystanhttp://www.blogger.com/profile/15653418292042541807noreply@blogger.com1