Quick notes on setting up Amazon S3 CORS headers.

Posted: March 18th, 2014 | Author: | Filed under: Uncategorized | No Comments »

This took me way to long to figure out.

  1. In the S3 interface, click the magnifying glass icon to the left of your bucket.
  2. Click the “Edit CORS Configuration” button. It should be right next to “Add Bucket Policy”
  3. You should already have a CORS XML file in here, if not mine looked like this :
    This CORS header allows all websites to perform GET requests against this resource.
  4. To reference the file, you must use the url structure [bucket].s3.amazonaws.com/[object]
  5. If using an img tag, it must contain the attribute¬†crossorigin=”anonymous”

Check out MDN for more information about CORS headers.


Introduction to the game

Posted: September 13th, 2013 | Author: | Filed under: Games | No Comments »

Now that my framework is nearing completion, I want to go back to why I started programming.

Games.

I have been working on one concept for some time, and will start development soon. As the project progresses I will post updates here. These posts will contain my progress, my ideas, my thoughts, my challenges. Today I’m going to start with one of my game design ideas.

 

Experience

In an RPG you tend to have characters who can level, and experience points which accumulate to increment your level. These experience points are a numeric abstraction of the feats you have accomplished in the past. It’s a one way hash of your characters life, translated into a number representing how awesome you are.

I want experience to represent something. I want to be able to go backwards from your experience into the story of your life. One standard system that combines your quest history, your kill stats, your exploration, your adventures. To pull this off, I’m going to leverage the standard Achievement system. No longer will kills and quests directly grant experience. Experience will be the sum of all of your achievements.

I know more values are necessary, but my basic ideas can be created with the two following tables.

Achievements

  • Title
  • Description
  • Type (exploration, kill, quest, etc)
  • Experience Value (this allows some achievements to be weighted more than others, based on difficulty or importance)

UserAchievements

  • User ID
  • Achievement ID
  • Progress (1 orc killed so far)
  • Status (complete, incomplete, failed, etc)
  • Start Date
  • Completion Date

I have designed these tables with some specific features in mind.

New Gameplay

  • These achievements represent the actions a person has performed in their life. They should tie into practical rewards and impact gameplay. If they have killed 10,000 orcs they probably are good at killing orcs, and someone probably knows it’s happening. Give direct combat bonuses, alter conversations, trigger new quests, or alter reputations.
  • Date tracking enables meta quests. Leaderboards, Fastest, Most efficient, World first.

New information for users

  • Users now have a list containing all of their actions. They should be able to wear them like medals, brag about them to friends. People should react to them differently, call them orc slayer
  • Easy to query the exact times a user hit each level, since every XP gaining action has a completion date
  • Show what actions a user took to level, give awesome graphs. Pie charts that say 70% of my experience was from kills, 25% from quests and 5% from exploration.
  • Compare this data with other users (like Steam). How many other people have completed this achievement? How long did it take people to complete this achievement? What level were they when they completed the achievement? As a user I would love to know all of this.

Administration benefits

  • Tracking this data can augment (or replace) some of the logs you take.
  • Each quest can have an assumed average execution time. If the quest took too long, was it because the quest is too hard?
  • If you find a quest is more difficult than you expected, you can increase the XP gained post-launch. You could even retroactively apply the xp bonus to players who missed out on the XP with a very simple db update.

Concerns

If I don’t provide XP on each kill the game might seem less rewarding. I will start without any per-kill XP, but I have ways to address this concern. I can try to make each kill more rewarding through other treasures, or visual/audio queues, or I could provide partial XP of the final achievement.¬† I have not yet decided if I want to investigate this concern further.

Let me know what you think about the concept. I would love to know if anyone has tried anything similar in the past.


New Routing Structure

Posted: July 31st, 2013 | Author: | Filed under: Programming, Roads | No Comments »

I have just implemented the new url routing structure into Roads. Lets start with the example :

Each key is a “URl Part”. I define a URL Part here as one value in the array resulted from url.split(‘/’);

The value for each URL Part defines the necessary information to render the url (eg “users” = “/users”). I use a standard controller/view structure for my code so you can see those keys here. Additional data (like templates, pre/post execution code, etc) could be defined here.

The “routes” key within each value defines child routes. The keys can be literals (eg “auth”) or variables (eg “#id”). Variable types are defined by the first character, # means only numbers, $ means any string value that does not contain the character “/”. The value of each child route can be defined identically to the parent route.

Child route values have one additional feature, they inherit any missing values from their parents. Not only are object keys inherited, but I have added an additional shortcut. Since views are likely to be the only thing that ever changes, you can forgo the objects entirely and have a route point directly to the view string (eg {“#id” : “one”} tells /users/#id to load the view “one” from within the controller “user”).

So lets unwrap the gist from above so you can see what a traditional router would look like.

In these traditional routes, you have tons of duplication, and have to iterate over every single route to find your match.

In Road’s router, you have much less typing and can skip many routes. If a route does not match the url, there’s no reason to check that route’s children.

In the end, this feels much more powerful and much less tedious. I think it will make routes more enjoyable to write.


Bifocals.js

Posted: October 24th, 2012 | Author: | Filed under: Programming, Roads | No Comments »

Yesterday I launched Bifocals.js, a node library for handling http responses.

It was my first big launch, and I learned a ton from it. Before I go into that, lets show some numbers.

  • Peaked at # 9 on Hacker News
  • 7,077 Page Views
  • 6,202 Unique Visitors
  • 56% United States
  • 70% Chrome
  • 48% Mac
  • 87% from news.ycombinator.com
  • Avg. Visit Duration: 00:00:17

 

That visit duration is abysmal. Clearly the docs need to be improved.

I received the best discussion via Facebook, and then Hacker News. No one initially knew what the hell my library did. So I wrote up a new description, which will be added to the docs later.


Node has a serious problem. It’s single threaded. That means that all the javascript you execute will stop any other javascript from executing.

Many people have developed techniques to solve this. Most of these techniques involve running multiple versions of your program and splitting traffic between them. Bifocals is not meant as a replacement for this technique. Bifocals is meant to help facilitate another technique for improving performance. Bifocals makes it incredibly easy to split your web page up into little tiny chunks. It might not be inherently obvious why this is useful, but it becomes slightly more clear with an understanding of the javascript event queue.

Any time an http request hits the server, it puts your server callback into a queue. Node processes this queue in order. Every time you handle a callback for an http request, a database request, any socket or file stuff in general, it uses this queue. Additionally, process.nextTick will add functions onto this queue.

If each of your functions operate quicker, it should allow for more parallel users. Each time a function completes it relinquishes control to another user, allowing them to do some processing. In a real world mix of pages that render at different speeds, faster requests should get out of the way while longer requests are still communicating with your database, or a third party API.

Bifocals not only allows your view functions to be smaller, but it allows them to operate out of order. All of your views can start performing IO at the same time, and no matter which one finishes first bifocals will render the final output accurately.

When all of these techniques are put together, theoretically it should create a faster overall page speed across the entire site. (I hope to have real stats soon)

 

If you don’t need these benefits, bifocals offers two additional nice features.

  • It abstracts away template rendering to a simple workflow, and allows you to use any core render system you want.
  • It provides easy access to http status codes, and the strange http standard associated with them.

 

Hopefully this is a little more clear. Thanks to everyone who had comments, I have some cool new features coming soon.


gfw renamed, welcome “roads”!

Posted: June 16th, 2012 | Author: | Filed under: gfw, Programming, Roads | No Comments »

I have renamed gfw.js (searching for gfw gives you references to the great firewall of china).

The new name is “roads”. You will be able to access it from roadsjs.com, and I have published it on npm (npm install roads).

There is currently a bug in the database layer making it unusable, but I will iron that out soon.


gfw.js static resource

Posted: April 25th, 2012 | Author: | Filed under: gfw, Programming | Tags: , , | No Comments »

I recently added a static resource to the list of example resources. This resource will render static files (such as javascript and css) with the appropriate mime type and last-modified headers. It also responds correctly to if-modified-since headers with a 304.

https://github.com/Dashron/gfw.js/blob/master/resources/static/static.desc.js

To accomplish this I had to make some structural changes to the view object. Now the template engine is loaded the very last second before you render a template. If a template is not rendered, we never create the engine. This allows us to switch the engine out easily while processing a request.

fs_module.stat retrieves the metadata of a file, and mtime is the last modified time. Everything else in the resource is pretty self explanitory.

I would like to stress though, this system is for DEVELOPMENT PURPOSES ONLY. I wrote it so I could get some experience writing more complex resources, and so that development could be a little easier. In a production environment I recommend some sort of proxy to serve your static files (such as nginx). It should be much less overhead.


gfw.js base templates added

Posted: April 25th, 2012 | Author: | Filed under: gfw, Programming | Tags: , , | No Comments »

I recently added a template property to the resource description.

This is an optional property which expects a function. The provided function will be passed one parameter, a view object.

This function lets you define a base template which will wrap around the response to any request. It most commonly would be used to apply any opening and closing html tags.

To use the base template, you should be aware of exactly how it is applied. Below is an example of its implementation.

 

If we were not going to have a base template, the variable view would be provided directly to your route. Since we have a base template, we first create a child view. This child will be the real view provided to your route, and once rendered it will fill the “content” template variable in the base template.

We then apply the template function to the parent view. This function should fill it with any necessary data, and then call view.render(template). The template will automatically be provided whatever route the user is actually requesting via the content variable.

Finally we switch the view with the child, so that any future routing uses that view object.

Additionally, I added a property to each the options within a route. This property is called ignore_template and will make sure the base template is not used.


gfw.js update

Posted: April 25th, 2012 | Author: | Filed under: gfw, Programming | Tags: , , | No Comments »

Since the last post, gfw.js has gone through some major changes. I had to rewrite the routing and resource system some so that routes included a new feature. This feature allows you to re-route from within a resource.

For example, this blog post has a title section, a series of blog posts, and a series of navigation links. There is no reason for all three of those sections to be located in the same template. The title and navigation will be used on many pages, so it would be more useful to have as a separate view with it’s own unique data. Sometimes this data will be more complex, such as a widget containing user data. Re-routing from within a resource allows you to generate html for a user widget by re-routing to that users page, but forcing it into a new template. The gist below might help explain.

 

So when I request /home it will use the first route. When I request /user/5 it will use the second route. Each request will work from your browser and return the template provided to view.render(template);

The fancy stuff happens in the re-route within the /home route. The route for /user/5 still is called, but it’s template has been overridden by user_box_small.html. Now when the re-routed /user/5 route calls view.render(‘user.html’), it ignores the provided template and ignores the http response. This re-routed render request will actually write into the parent view, meaning the view that originally spawned the child view at line 6.

The first parameter of view.child is the template variable that will become the entire contents of the child view. The second parameter is a template override which allows you to override default templates for specific sections of your site.

One big question you might have is that since this is node, how will this work asynchronously? If the parent is rendered before the child, will the parent be missing the child data?

The view handles all of that for you. If a parent view is rendered before a child, the parent waits for the children to finish. Once the last child is finished rendering, it informs the parent that everything is ready and it can render whenever.

The one condition for rendering views this way, is you MUST create any child views before you render your template, but I have yet to find a reason someone would need to add a child view out of line with a render call.


gfw.js

Posted: December 14th, 2011 | Author: | Filed under: gfw, Programming | Tags: , , | No Comments »

I have just released an early version of my node.js framework, gfw.js.

https://github.com/dashron/gfw.js

The framework helps in writing resource oriented web services, and has some built in functionality to turn that into single page web apps, similar to gmail. I will add a writeup in the near future with more information.

If you want to dive in, you first must put the client side sizzle library into /resources/gfw/templates/js. You can find it at sizzlejs.com

Once that is complete, simply call “node main.js” from the root directory of the project and your webserver should be running. Navigate to localhost:8125 and you will see the example site.

I plan on making the example site more interesting in the near future, but for now everything happens on load so it’s not visually impressive. My next step is to clean up some of the abstraction, so that client and server side JavaScript use identical interfaces.


I Will Return

Posted: July 15th, 2011 | Author: | Filed under: Uncategorized | No Comments »

I promise. Too many things on my plate right now.

Girlfriend.

Node.js.

2 Unnamed Media Projects.

My ZAFT Project.

New Apartment.

Ocarina of Time 3ds.

Once things calm down I will import my old posts, and start writing new ones.