<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Nylira: Interaction Design & Web Development]]></title><description><![CDATA[The newest articles about interaction design and web development. Brought to you by Nylira.]]></description><link>http://nylira.com/</link><image><url>http://nylira.com/assets/img/favicon.png</url><title>Nylira: Interaction Design &amp; Web Development</title><link>http://nylira.com/</link></image><generator>RSS for Node</generator><lastBuildDate>Thu, 22 Jun 2023 19:03:31 GMT</lastBuildDate><atom:link href="http://nylira.com/rss.xml" rel="self" type="application/rss+xml"/><author><![CDATA[Peng Zhong]]></author><pubDate>Thu, 22 Jun 2023 19:03:31 GMT</pubDate><copyright><![CDATA[2023 Peng Zhong]]></copyright><language><![CDATA[en]]></language><managingEditor><![CDATA[Peng Zhong]]></managingEditor><webMaster><![CDATA[Peng Zhong]]></webMaster><ttl>60</ttl><item><title><![CDATA[Designing Tetris for mobile devices in JavaScript]]></title><description><![CDATA[<p>I made Tetris in JavaScript. It plays well on both <span class="caps">PC</span> and mobile browsers. Give it shot in fullscreen <a href="http://tetris.nylira.com">here</a>. Or play the embedded version<span class="widont">&nbsp;</span>below.</p>
<iframe src="http://tetris.nylira.com" width="360" height="640"></iframe>

<h2 id="high-scores">High Scores</h2>
<p>Your high scores are persisted through your browser&#39;s localStorage. This means that this game is a purely client-side application, and can be played offline without the<span class="widont">&nbsp;</span>internet.</p>
<h2 id="libraries">Libraries</h2>
<p>I made great use out of these <span class="caps">JS</span><span class="widont">&nbsp;</span>libraries:</p>
<ul>
<li><a href="https://github.com/mightyiam/combokeys">Combokeys</a> for keyboard<span class="widont">&nbsp;</span>shortcuts.</li>
<li><a href="http://www.pixijs.com/">Pixi.js</a> as my 2D rendering<span class="widont">&nbsp;</span>engine.</li>
</ul>
<h2 id="source">Source</h2>
<p>The source code for my Tetris implementation is available on GitHub at <a href="https://github.com/nylira/tetris">github.com/nylira/tetris</a>. Feel free to take a<span class="widont">&nbsp;</span>look!</p>
<p>And if you want to play it, go here: <a href="http://nylira.com">tetris.nylira.com</a></p>
]]></description><link>http://nylira.com/tetris</link><guid isPermaLink="true">http://nylira.com/tetris</guid><dc:creator><![CDATA[Peng Zhong]]></dc:creator><pubDate>Mon, 16 Mar 2015 00:00:00 GMT</pubDate></item><item><title><![CDATA[Don't start a front end project without these five essential libraries]]></title><description><![CDATA[<p>I find the following libraries for <a href="https://iojs.org/">io.js</a> to be essential to a robust web project in 2015. The JavaScript front end development stack is changing dramatically month by month, but solid, usable tools don&#39;t come by very<span class="widont">&nbsp;</span>often.</p>
<h2 id="put-everything-together-with-browserify">Put everything together with<span class="widont">&nbsp;</span>Browserify</h2>
<p>Browserify is a godsend. Being able to manage my front end JavaScript with <span class="caps">NPM</span> feels like the future. This library makes just about anything possible. Grab the companion Watchify library too to watch for changes to your<span class="widont">&nbsp;</span>files.</p>
<p>Get it: <code>npm install browserify watchify --save</code></p>
<h2 id="deal-with-old-versions-of-ie-with-modernizr">Deal with old versions of <span class="caps">IE</span> with <a href="http://modernizr.com/">Modernizr</a></h2>
<p>The shackles of old version of <span class="caps">IE</span> still haunt us. Modernizr makes it a bit less painful by letting us target unsupported features with a simple body<span class="widont">&nbsp;</span>class.</p>
<p>Get it: <a href="http://modernizr.com/">modernizr.com</a></p>
<h2 id="use-koa-for-your-web-serving-needs">Use <a href="http://koajs.com/">Koa</a> for your web serving<span class="widont">&nbsp;</span>needs</h2>
<p>Koa is a lightweight web server perfect for localhost development. It makes use of <span class="caps">ES6</span> features like promises and yield to return content for <span class="caps">HTTP</span> requests, but you don&#39;t have to learn about that to use<span class="widont">&nbsp;</span>it.</p>
<p>Get it: <code>npm install koa --save</code></p>
<h2 id="manage-your-templates-with-react">Manage your templates with <a href="http://facebook.github.io/react/">React</a></h2>
<p>React is a little different from your ordinary <span class="caps">HTML</span> templating library. You write your templates in <span class="caps">JSX</span> (or with <span class="caps">JS</span> functions, as I prefer) in a JavaScript. However, it offers the most performant way to update your <span class="caps">HTML</span> through a virtual<span class="widont">&nbsp;</span><span class="caps">DOM</span>.</p>
<p>Get it: <code>npm install react --save</code></p>
<h2 id="simplify-your-css-with-stylus">Simplify your <span class="caps">CSS</span> with <a href="http://learnboost.github.io/stylus/">Stylus</a></h2>
<p>Stylus makes working with <span class="caps">CSS</span> <a href="../stylus-the-revolutionary-successor-to-css">easier</a> than any other <span class="caps">CSS</span> preprocessor. Get the nib utility library too, for easy stylesheet resets, browser prefixes, and other useful<span class="widont">&nbsp;</span>mixins.</p>
<p>Get it: <code>npm install stylus nib --save</code></p>
]]></description><link>http://nylira.com/essential-libraries</link><guid isPermaLink="true">http://nylira.com/essential-libraries</guid><dc:creator><![CDATA[Peng Zhong]]></dc:creator><pubDate>Tue, 10 Mar 2015 00:00:00 GMT</pubDate></item><item><title><![CDATA[Building Snake with JavaScript in 2015]]></title><description><![CDATA[<p>I made the game Snake in JavaScript. It plays well on both <span class="caps">PC</span> and mobile browsers. Give it a shot! <a href="http://snake.nylira.com">snake.nylira.com</a></p>
<div class="figure">
  <img src="../assets/images/snake/gameplay.png" alt="Snake gameplay" />
  <div class="figcaption">
    <p>Yes, I lost this game in order to show you a<span class="widont">&nbsp;</span>screenshot.</p>
  </div>
</div>

<h2 id="controls">Controls</h2>
<p>  There are multiple control schemes in place so you can play it however you want. For mobile, you may either tap the on screen buttons or swipe in any direction. For <span class="caps">PC</span>, you have the added options of <span class="caps">WASD</span> and arrow<span class="widont">&nbsp;</span>keys.</p>
<h2 id="high-scores">High Scores</h2>
<p>  Your high scores are persisted through your browser&#39;s localStorage. This means that this game is a purely client-side application, and can be played offline without the<span class="widont">&nbsp;</span>internet.</p>
<h2 id="libraries">Libraries</h2>
<p>  I made great use out of the following JavaScript<span class="widont">&nbsp;</span>libraries:</p>
<ul>
<li><a href="https://github.com/mightyiam/combokeys">Combokeys</a> for keyboard<span class="widont">&nbsp;</span>shortcuts.</li>
<li><a href="https://github.com/ftlabs/fastclick">FastClick</a> to remove the 300ms delay on touch input on mobile<span class="widont">&nbsp;</span>websites.</li>
<li><a href="http://http://hammerjs.github.io/">Hammer.<span class="caps">JS</span></a> for touch<span class="widont">&nbsp;</span>gestures.</li>
<li><a href="http://goldfirestudios.com/blog/104/howler.js-Modern-Web-Audio-Javascript-Library">howler.js</a> for WebAudio<span class="widont">&nbsp;</span>sound. </li>
<li><a href="http://www.pixijs.com/">Pixi.js</a> for WebGL rendering wi<a href="http://th">http://th</a> a Canvas<span class="widont">&nbsp;</span>fallback.</li>
</ul>
<h2 id="source">Source</h2>
<p>  The source code for my Snake implementation is available on GitHub at <a href="https://github.com/nylira/snake">github.com/nylira/snake</a>. Feel free to take a<span class="widont">&nbsp;</span>look!</p>
<p>  And if you want to play it, go here: <a href="http://nylira.com">snake.nylira.com</a></p>
]]></description><link>http://nylira.com/snake</link><guid isPermaLink="true">http://nylira.com/snake</guid><dc:creator><![CDATA[Peng Zhong]]></dc:creator><pubDate>Tue, 27 Jan 2015 00:00:00 GMT</pubDate></item><item><title><![CDATA[Optimize your PNG images in under 80 seconds]]></title><description><![CDATA[<p>Contributors to prism-break.org have been adding software logos from everywhere around the internet. Almost none of them are fully optimized for quick user<span class="widont">&nbsp;</span>downloads.</p>
<h2 id="enter-pngcrush">Enter pngcrush</h2>
<p>pngcrush is a command line tool that attempts to reduce the file size of your <span class="caps">PNG</span> files losslessly. It does this by attempting a large number of compression methods and comparing their results to see which offers the greatest file size<span class="widont">&nbsp;</span>reduction.</p>
<p>Smaller file sizes mean a snapper user experience. It also improves your search rankings in<span class="widont">&nbsp;</span>Google.</p>
<p>Install pngcrush with<span class="widont">&nbsp;</span>npm:</p>
<pre><code>npm install pngcrush
</code></pre><h2 id="using-pngcrush-on-a-single-png-file">Using pngcrush on a single <span class="caps">PNG</span><span class="widont">&nbsp;</span>file</h2>
<p>Let&#39;s try using pngcrush on Gentoo Linux&#39;s famous &quot;g&quot; logo. You can find a <span class="caps">PNG</span> version of it on <a href="https://www.gentoo.org/main/en/name-logo.xml">their<span class="widont">&nbsp;</span>website</a>.</p>
<div class="figure">
  <img src="../assets/images/pngcrush/gblend.png" alt="Gentoo Linux logo" />
  <div class="figcaption">
    <p>The Gentoo Linux logo. Size: 1,109,332<span class="widont">&nbsp;</span>bytes</p>
  </div>
</div>

<p>This is the command we&#39;ll<span class="widont">&nbsp;</span>use:</p>
<pre><code>pngcrush -rem allb -brute -reduce gblend.png gentoo.png
</code></pre><p>These are the results I<span class="widont">&nbsp;</span>get:</p>
<pre><code>Best pngcrush method        = 112 (ws 15 fm 5 zl 8 zs 1) =    863400
for output to gentoo.png
(22.17% critical chunk reduction)
(22.17% filesize reduction)
CPU time decoding 4.954, encoding 74.960, other 0.022, total 79.935 sec.
</code></pre><p>And here is the optimized version of the<span class="widont">&nbsp;</span>logo:</p>
<div class="figure">
  <img src="../assets/images/pngcrush/gblend-optimized.png" alt="Gentoo Linux logo (optimized)" />
  <div class="figcaption">
    <p>The Gentoo Linux logo after being pngcrushed. Size: 863,400<span class="widont">&nbsp;</span>bytes</p>
  </div>
</div>

<p>There is no visual difference, but the file is 864 <span class="caps">KB</span> instead of 1.1 <span class="caps">MB</span>. That&#39;s 22% less transfer required for your users. Isn&#39;t that<span class="widont">&nbsp;</span>great!</p>
<h2 id="using-pngcrush-to-recursively-crush-directories-of-png-files">Using pngcrush to recursively crush directories of <span class="caps">PNG</span><span class="widont">&nbsp;</span>files</h2>
<p>I use this following command (<a href="http://www.commandlinefu.com/commands/view/10996/pngcrush-all-.png-files-in-the-directory">found here</a>) to recursively crush all the images in the assets folder of my <span class="caps">PRISM</span> Break<span class="widont">&nbsp;</span>project.</p>
<pre><code>find -f . png | while read line; do pngcrush -ow -brute $line; done
</code></pre><p>The last time I ran this command, I reduced the size of my images folder from 19.3 <span class="caps">MB</span> to 17.6 <span class="caps">MB</span>. Due to the light weight of the <span class="caps">HTML</span>, and <span class="caps">CSS</span> this means that visitors to <a href="https://prism-break.org">https://prism-break.org</a> will load the site nearly 9% faster. Definitely worth<span class="widont">&nbsp;</span>it.</p>
]]></description><link>http://nylira.com/pngcrush</link><guid isPermaLink="true">http://nylira.com/pngcrush</guid><dc:creator><![CDATA[Peng Zhong]]></dc:creator><pubDate>Wed, 21 Jan 2015 00:00:00 GMT</pubDate></item><item><title><![CDATA[A Tour of Go - Exercise Solutions]]></title><description><![CDATA[<p>I&#39;m trying to pick up the basics of the <a href="http://golang.org/">Go</a> programming language. Here are my solutions for the exercises presented in &#39;<a href="http://tour.golang.org/">A Tour of Go</a>&#39;. </p>
<h2 id="exercise-loops-and-functions-25">Exercise: Loops and Functions <a href="http://tour.golang.org/#25">#25</a></h2>
<p>The following code returns an approximation for the square root of 2 and compares the result to Go&#39;s <code>math.Sqrt()</code> function.</p>
<pre><code>package main

import (
    &quot;fmt&quot;
    &quot;math&quot;
)

func Sqrt(x float64) float64 {

    // initialize variables
    z, d := float64(1), float64(1)

    // if delta is greater than 1e-15, seek closer approximation
    for d &gt; 1e-15 {
        z0 := z
        z = z - (z * z - x)/(2 * z)
        d = math.Abs(z - z0)
    }
    return z

}

func main() {
    fmt.Println(Sqrt(2))
    fmt.Println(math.Sqrt(2))
}
</code></pre><h2 id="exercise-slices-38">Exercise: Slices <a href="http://tour.golang.org/#38">#38</a></h2>
<p>The following code creates an image with a repeating<span class="widont">&nbsp;</span>pattern.</p>
<pre><code>package main

import &quot;code.google.com/p/go-tour/pic&quot;

func Pic(dx, dy int) [][]uint8 {

    // initialize the image
    image := make([][]uint8, dy)

    // iterate over each pixel
    for x := 0; x &lt; dy; x++ {
        image[x] = make([]uint8, dx)
        for y := 0; y &lt; dx; y++ {

            // set a color value for each pixel
            image[x][y] = uint8((x ^y) * (x ^ y))

        }
    }
    return image
}

func main() {
    pic.Show(Pic)
}
</code></pre><h2 id="exercise-maps-43">Exercise: Maps <a href="http://tour.golang.org/#43">#43</a></h2>
<p>The following code counts the number of instances of each word within a<span class="widont">&nbsp;</span>string.</p>
<pre><code>package main

import (
    &quot;code.google.com/p/go-tour/wc&quot;
    &quot;strings&quot;
)

func WordCount(s string) map[string]int {

    // initialize the wordMap variable
    wordMap := make(map[string]int)

    // separate the strings into words
    words := strings.Fields(s)

    // iterate over the words to count each instance
    for _, word := range words {
        wordMap[word]++
    }

    return wordMap
}

func main() {
    wc.Test(WordCount)
}
</code></pre><h2 id="exercise-fibonacci-closure-46">Exercise: Fibonacci closure <a href="http://tour.golang.org/#46">#46</a></h2>
<p>A simple Fibonacci sequence function. The Fibonacci sequence is the sequence of numbers where the <code>value(n) = value(n-1) + value (n-2)</code> with the seed values <code>value(0) = 0</code> and <code>value(1) = 1</code>.</p>
<pre><code>package main

import &quot;fmt&quot;

// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
    first, second := 0, 1
    return func() int {
        first, second = second, first + second
        return first
    }
}

func main() {
    f := fibonacci()
    for i := 0; i &lt; 10; i++ {
        fmt.Println(f())
    }
}
</code></pre><h2 id="advanced-exercise-complex-cube-roots-50">Advanced Exercise: Complex cube roots <a href="http://tour.golang.org/#50">#50</a></h2>
<p>The following function uses Newton&#39;s method for finding an approximation for cube roots and iterates over it 1000 times to get a rough value for a cube root of a<span class="widont">&nbsp;</span>number.</p>
<pre><code>package main

import(
    &quot;fmt&quot;
    &quot;math/cmplx&quot;
)

func Cbrt(x complex128) complex128 {
    z := complex128(1)

    for i := 0; i &lt; 1000; i++ {
        z = z - (cmplx.Pow(z, complex128(3)) - x)/(3 * cmplx.Pow(z, complex128(2)))
    }
    return z

}

func main() {
    fmt.Println(Cbrt(2))
}
</code></pre><h2 id="exercise-errors-58">Exercise: Errors <a href="http://tour.golang.org/#58">#58</a></h2>
<p>Returning an error if the user tries to find the square root of a negative<span class="widont">&nbsp;</span>number.</p>
<pre><code>package main

import (
    &quot;fmt&quot;
)

// error type
type ErrNegativeSqrt float64

// error function for the error type
func (e ErrNegativeSqrt) Error() string {
    return fmt.Sprintf(
        &quot;Can&#39;t find the Sqrt of a negative number: %v&quot;, float64(e))
}

func Sqrt(f float64) (float64, error) {

    // return error if number is negative
    if f &lt; 0 {
        return 0, ErrNegativeSqrt(f)

    // otherwise find an approximation for the square root
    } else {
        z := float64(1)
        for i := 0; i &lt; 1000; i++ {
            z = z - (z * z - f)/(2 * z)
        }
        return z, nil
    }
}

func main() {
    fmt.Println(Sqrt(2))
    fmt.Println(Sqrt(-2))
}
</code></pre><h2 id="exercise-http-handlers-60">Exercise: <span class="caps">HTTP</span> Handlers <a href="http://tour.golang.org/#60">#60</a></h2>
<pre><code>package main

import (
    &quot;net/http&quot;
    &quot;fmt&quot;
)

type String string

type Struct struct {
    Greeting string
    Punctuation string
    Who string
}

func (s String) ServeHTTP(
    w http.ResponseWriter,
    r *http.Request) {
    fmt.Fprint(w, s)
}

func (s Struct) ServeHTTP(
    w http.ResponseWriter,
    r *http.Request) {
    fmt.Fprint(w, s.Greeting, s.Punctuation, s.Who)
}

func main() {
  http.Handle(&quot;/string&quot;, String(&quot;I&#39;m a frayed knot.&quot;))
  http.Handle(&quot;/struct&quot;, &amp;Struct{&quot;Hello&quot;, &quot;:&quot;, &quot;Gophers!&quot;})
    http.ListenAndServe(&quot;localhost:4000&quot;, nil)
}
</code></pre><h2 id="exercise-images-62">Exercise: Images <a href="http://tour.golang.org/#62">#62</a></h2>
<p>This function defines and creates a test<span class="widont">&nbsp;</span>image.</p>
<pre><code>package main

import (
    &quot;code.google.com/p/go-tour/pic&quot;
    &quot;image&quot;
    &quot;image/color&quot;
)

// create the custom image type
type Image struct{
    width, height int
    pColor uint8
}

// set the image dimensions and location
func (self *Image) Bounds() image.Rectangle {
  return image.Rect(0, 0, self.width, self.height)
}

// set the image color model
func (self *Image) ColorModel() color.Model {
  return color.RGBAModel
}

// set the image color per pixel
func (self *Image) At(x, y int) color.Color {
  return color.RGBA{
        self.pColor + uint8(x), self.pColor + uint8(y), 255, 255}
}

// create and show the image
func main() {
    m := Image{100, 100, 128}
    pic.ShowImage(&amp;m)
}
</code></pre><h2 id="exercise-rot13-reader-63">Exercise: Rot13 Reader <a href="http://tour.golang.org/#63">#63</a></h2>
<p>The following code decrypts strings of Rot13<span class="widont">&nbsp;</span>text.</p>
<pre><code>package main

import (
    &quot;io&quot;
    &quot;os&quot;
    &quot;strings&quot;
)

type rot13Reader struct {
    r io.Reader
}

func (rot rot13Reader) Read(p []byte) (n int, err error) {

  n, err = rot.r.Read(p)

  // for each letter read from io.Reader
  for i := 0; i &lt; len(p); i++ {


    // if the letter&#39;s index is between A - N, add 13 to its index
    if (p[i] &gt;= &#39;A&#39; &amp;&amp; p[i] &lt; &#39;N&#39;) || (p[i] &gt;=&#39;a&#39; &amp;&amp; p[i] &lt; &#39;n&#39;) {
      p[i] += 13

    // if the letter&#39;s index is between M - Z, subtract 13 from its index
    } else if (p[i] &gt; &#39;M&#39; &amp;&amp; p[i] &lt;= &#39;Z&#39;) || (p[i] &gt; &#39;m&#39; &amp;&amp; p[i] &lt;= &#39;z&#39;){
      p[i] -= 13
    }

  }
  return
}

// test to make sure it works
func main() {
    s := strings.NewReader(
        &quot;Lbh penpxrq gur pbqr!&quot;)
    r := rot13Reader{s}
    io.Copy(os.Stdout, &amp;r)
}
</code></pre>]]></description><link>http://nylira.com/a-tour-of-go-solutions</link><guid isPermaLink="true">http://nylira.com/a-tour-of-go-solutions</guid><dc:creator><![CDATA[Peng Zhong]]></dc:creator><pubDate>Fri, 10 Oct 2014 00:00:00 GMT</pubDate></item><item><title><![CDATA[The Making of Nylira v4]]></title><description><![CDATA[<p>In this article I&#39;ll go through the reasons why I rebuilt my site from the ground up, the objectives in my newest design, and my thoughts for future improvement. Hopefully you can find something in here to help you with your own site<span class="widont">&nbsp;</span>design.</p>
<h2 id="why-do-i-need-to-redesign-">Why Do I Need To<span class="widont">&nbsp;</span>Redesign?</h2>
<p>I need to redesign my site not because I&#39;m bored of the old design, but because I&#39;ve found several major problem areas with the previous<span class="widont">&nbsp;</span>design.</p>
<p><strong>1. There&#39;s no narrative in my old site.</strong> There was so little text in the previous design that all a visitor sees is a list of links. A list of links to a large number of topics is not friendly to most of my visitors. Visitors to a website tend to have an expectation of what they&#39;ll see, and my old &quot;table of contents&quot;-like layout is not what they<span class="widont">&nbsp;</span>want.</p>
<p><strong>2. There was no useful navigation in my old site.</strong> There was, in fact, navigation. But it required scrolling through the entire front page of my site. As my site homepage was quite long, it&#39;s not hard to imagine I was losing visitors who had a specific inquiry in mind but got lost in my link<span class="widont">&nbsp;</span>list.</p>
<p><strong>3. A long, linear page design is not an efficient use of space on larger screens.</strong> My previous design revolved around a vertical list of links in no particular order of importance. The linearity of the design is actually not a problem. The problem is that I stuffed the list with far too many links, making reading them an arduous exercise. On larger displays especially, the lack of differently sized paged elements made the site design rather<span class="widont">&nbsp;</span>tedious.</p>
<h2 id="redesign-objectives">Redesign Objectives</h2>
<p>Before I show you the code behind the site, I want to go into the reasoning for building the v4 site the way I<span class="widont">&nbsp;</span>have.</p>
<p><strong>The site&#39;s content must be easy to access on all devices.</strong> I don&#39;t want mobile users to be stuck with the desktop version of the site. It&#39;s a pain to read wide columns text on a phone. To make my site accessible to as many devices as possible, I went ahead with <a href="../mobile-first">mobile first<span class="widont">&nbsp;</span>design</a>.</p>
<p><strong>The site must be secure as possible.</strong> I&#39;m a web designer, not a system administrator. While I could have used a <span class="caps">CMS</span> like Wordpress or a framework like Rails, I don&#39;t have the time or energy to constantly secure my software stack against exploits.  To this end, I decided to make my site entirely static <span class="caps">HTML</span> and <span class="caps">CSS</span>, with a bit of client-side<span class="widont">&nbsp;</span><span class="caps">JS</span>.</p>
<p><strong>I want to learn some programming.</strong> While I could have used one of many static site generators on GitHub, I decided to roll my own generator with LiveScript, Jade, and Stylus. I realize I&#39;m reinventing the wheel here, but building my own site generator made me learn a lot of new things I never would have<span class="widont">&nbsp;</span>otherwise.</p>
<p><strong>The site has to be incredibly easy to update.</strong> I find that a lot of my ideas for articles and blog posts die before I can publish them online, due to the friction involved in web publishing. I want to keep editing and publishing as simple as possible to reduce that friction. Thus I picked a syntax that is pretty much as close to plain text as possible:<span class="widont">&nbsp;</span>Markdown.</p>
<p><strong>The site should showcase my portfolio.</strong> Web design portfolios look best with a dark gray or black background. My site&#39;s colors should be subtle in order to better present the work I have done. Thus I&#39;m going back to Nylira v2&#39;s color<span class="widont">&nbsp;</span>scheme.</p>
<h2 id="technical-details">Technical Details</h2>
<p>To build my static site generator, I decided to use many of the same node.js libraries I used for <a href="../on-prism"><span class="caps">PRISM</span> Break</a>. I would write all the code in LiveScript. The templates would be powered by Jade. The <span class="caps">CSS</span> would be pre-processed by Stylus. The content would be written in<span class="widont">&nbsp;</span>Markdown.</p>
<h2 id="todo">Todo</h2>
<p>This redesign is a work in progress, and there are still things I want to do to it. Here&#39;s a list of things I still want to add to the<span class="widont">&nbsp;</span>site:</p>
<ul>
<li>Project logos for the <a href="../projects/">Projects</a> index<span class="widont">&nbsp;</span>page.</li>
<li>Consider adding categories or filters for the <a href="../articles/">Articles</a><span class="widont">&nbsp;</span>page.</li>
<li>Next/Previous article buttons for individual article<span class="widont">&nbsp;</span>pages.</li>
</ul>
]]></description><link>http://nylira.com/making-of-nylira-v4</link><guid isPermaLink="true">http://nylira.com/making-of-nylira-v4</guid><dc:creator><![CDATA[Peng Zhong]]></dc:creator><pubDate>Mon, 29 Sep 2014 00:00:00 GMT</pubDate></item><item><title><![CDATA[Maze Generation in Unreal Engine 4]]></title><description><![CDATA[<p>I&#39;m developing an Action <span class="caps">RPG</span> from scratch using Unreal Engine 4. I switched recently from Unity due to <span class="caps">UE4</span>&#39;s source code access and vastly superior performance. Here&#39;s the progress with the dungeon generation so<span class="widont">&nbsp;</span>far.</p>
<p>First, I worked on implementing the Growing Tree algorithm with Unreal Blueprint. I learned a lot about maze generation algorithms from <a href="http://weblog.jamisbuck.org/2011/2/7/maze-generation-algorithm-recap">Jamis Buck</a> and <a href="http://www.astrolog.org/labyrnth/algrithm.htm">Think<span class="widont">&nbsp;</span>Labyrinth</a>.</p>
<div class='figure max'>
  <img src="../assets/images/arpg/grid-small.png" alt="Grid small" />
  <div class='figcaption'>The grid generated with 10x10 settings.</div>
</div>

<div class='figure max'>
  <img src="../assets/images/arpg/grid-large.png" alt="Grid large" />
  <div class='figcaption'>The grid generated with 14x14 settings.</div>
</div>

<h2 id="tile-tests">Tile Tests</h2>
<p>I haven&#39;t decided what setting to use for the game yet. I&#39;m experimenting with tile designs to see what looks good from a top-down<span class="widont">&nbsp;</span>perspective:</p>
<div class='figure max'>
  <img src="../assets/images/arpg/scifi-tiles.jpg" alt="Scifi tiles" />
  <div class='figcaption'>Some prototype map tiles rendered in Modo 801.</div>
</div>
]]></description><link>http://nylira.com/maze-generation-in-unreal-engine-4</link><guid isPermaLink="true">http://nylira.com/maze-generation-in-unreal-engine-4</guid><dc:creator><![CDATA[Peng Zhong]]></dc:creator><pubDate>Sun, 27 Apr 2014 00:00:00 GMT</pubDate></item><item><title><![CDATA[Simple Games]]></title><description><![CDATA[<p>I&#39;ve been interested in game development ever since I was a kid. I&#39;ve decided to dedicate some of my time in 2014 to game making: here are the results so<span class="widont">&nbsp;</span>far.</p>
<h2 id="roll-a-ball">Roll a Ball</h2>
<p>This game is based on one of the first Unity3D tutorials called &quot;Roll A Ball&quot;. I&#39;ve fleshed it out a bit with custom 3d models, textures, and particle<span class="widont">&nbsp;</span>effects.</p>
<p><img src="../assets/images/rollaball-80q.jpg" alt="Roll A Ball screenshot" /></p>
<ul>
<li><a href="http://files.nylira.com/games/nylira-rollaball-mac.zip">Download Mac</a></li>
<li><a href="http://files.nylira.com/games/nylira-rollaball-win.zip">Download Windows</a></li>
<li><a href="http://files.nylira.com/games/nylira-rollaball-linux.zip">Download Linux</a></li>
</ul>
]]></description><link>http://nylira.com/simple-games</link><guid isPermaLink="true">http://nylira.com/simple-games</guid><dc:creator><![CDATA[Peng Zhong]]></dc:creator><pubDate>Wed, 05 Mar 2014 00:00:00 GMT</pubDate></item><item><title><![CDATA[Useful Unix Commands]]></title><description><![CDATA[<p>Here are some terminal snippets I like to keep at hand. The most useful commands can be easily forgotten because you just don&#39;t use them<span class="widont">&nbsp;</span>enough.</p>
<h2 id="source">source</h2>
<p>Want your Vim configuration on another computer? Consider checking it into source control. Then, add this line to your <code>~/.vimrc</code> file.</p>
<pre><code>source /your-git-repo/vimrc
</code></pre><h2 id="zmv">zmv</h2>
<p>If you&#39;re using zsh, you should know it comes with zmv. Here&#39;s how to remove a prefix from a bunch of<span class="widont">&nbsp;</span>files.</p>
<pre><code>zmv &#39;prefix-(*)&#39; &#39;$1&#39;
</code></pre><h2 id="recursively-delete-specific-file-or-folder">recursively delete specific file or<span class="widont">&nbsp;</span>folder</h2>
<p>For a particular<span class="widont">&nbsp;</span>folder:</p>
<pre><code>find . -type d -name &#39;.git&#39; -print -exec rm -rf {} \;
</code></pre><p>For a particular<span class="widont">&nbsp;</span>file:</p>
<pre><code>find . -name &#39;.DS_Store&#39; -print -exec rm -rf {} \;
</code></pre>]]></description><link>http://nylira.com/unix-commands</link><guid isPermaLink="true">http://nylira.com/unix-commands</guid><dc:creator><![CDATA[Peng Zhong]]></dc:creator><pubDate>Thu, 30 Jan 2014 00:00:00 GMT</pubDate></item><item><title><![CDATA[Common UX Problems]]></title><description><![CDATA[<p>A selection of common <span class="caps">UX</span> problem areas and possible<span class="widont">&nbsp;</span>solutions.</p>
<h2 id="1-allowing-users-to-shoot-themselves-in-the-foot-by-permanently-deleting-their-data-">1. Allowing users to shoot themselves in the foot by permanently deleting their<span class="widont">&nbsp;</span>data.</h2>
<p>Disk-space is cheap, and user whims are fickle. If you can absorb the extra costs, I suggest never permanently deleting anything a user creates, unless they cancel their account. Give your user a history page where they can restore the state of everything they&#39;ve ever created or uploaded with your app. When they screw up (which they invariable will), they&#39;ll love you for thinking about the<span class="widont">&nbsp;</span>issue.</p>
<h2 id="2-interrupting-user-interaction-with-unimportant-modal-dialog-windows-">2. Interrupting user interaction with unimportant modal dialog<span class="widont">&nbsp;</span>windows.</h2>
<p>Instead of rudely throwing a modal dialog in your user&#39;s face, consider using Gmail&#39;s method for atomic operations: soft delete. After every action, Gmail displays a nonintrusive status message at the top of the screen. The message tells the user exactly what&#39;s occured&#8211;e.g., &quot;This conversation has been archived.&quot;&#8211;along with a simple &quot;Undo&quot;<span class="widont">&nbsp;</span>link.</p>
<p>Why is soft delete better than modal confirmation windows? For one, this method allows the user to delete faster by skipping a step (the modal middleman). Modal windows are intrusive, workflow-breaking, and force users user to make immediate decisions. Inline undos are far more user-friendly because the entire web app stays usable, instead of being backgrounded. Let&#39;s face it&#8211;most deleted files are never wanted<span class="widont">&nbsp;</span>back.</p>
<h2 id="3-not-allowing-users-to-do-batch-operations-with-a-list-or-grid-of-content-">3. Not allowing users to do batch operations with a list or grid of<span class="widont">&nbsp;</span>content.</h2>
<p>Native file managers allow clicking and dragging to lasso multiple documents. We&#39;ve used this simple operation on our desktop for years, but it has yet to show up online. Select-lassos could work very well for photo-oriented<span class="widont">&nbsp;</span>apps.</p>
<h2 id="4-forcing-the-use-of-lightboxes-in-image-galleries-">4. Forcing the use of lightboxes in image<span class="widont">&nbsp;</span>galleries.</h2>
<p>Lightboxes break the <span class="caps">UI</span> conventions of the user&#39;s operating systems. The non-standard chrome tends to difficult to close and impossible to move. Solution: <code>&lt;a href=image.jpg&gt;</code> with a magnify icon. Let users decide if they want to open the image in a new window or<span class="widont">&nbsp;</span>not.</p>
]]></description><link>http://nylira.com/common-ux-problems</link><guid isPermaLink="true">http://nylira.com/common-ux-problems</guid><dc:creator><![CDATA[Peng Zhong]]></dc:creator><pubDate>Thu, 30 Jan 2014 00:00:00 GMT</pubDate></item></channel></rss>