Project Archer – part 1 – concept

Summary:

Creating a close to real-time MMO archer game in Javascript.

((TL;DR jump to Development Plan))

History:

I’m a big fan of game mechanics, everything else may come second, but if the eye-hand challenge don’t feel right, the game most certainly goes down the drain.

The inspiration for this project came about 5 years ago:

Game design

I’ve been thinking of this project since i first shot birds at Bowman 2. The game played under this mode (sandbox) on Android 2, is dead simple. Drag and release to shoot an arrow! Simple but interesting graphic behaviours emerge. Like one arrow hitting 2 or more birds, one arrow that goes up 90 deg, and hit your archer in the head! Maybe go turbo and create an arrow storm!

Screen Shot 2016-03-08 at 4.15.21 PM.png

None of the effects I mentioned give out any score, there is no positive reinforcement mechanism either! It’s plain that screen made for sadistic individuals like myself. And yes, i got tired of it quickly, but still, the mechanics just felt so good for a few minutes.

Add MMO capabilities, a persistent world, one arrow that would teleport my character so now it can move through the scenario, of course some level design.. easy (not easy).

But then I thought, that’s too simple.. I want to embed some great elemental combinations, like Magicka! That would make the game more dynamic and engaging. Of course it would at least double development time, but not a single fuck is given about it in imagination world.

Of course I’m also a big fan of LoL, Kog’Maw being my favourite champion. So i thought i’d embed a somewhat similar cooldown system for each arrow, probably a skill tree would also be in place.

kog-maw-dance-o

Well then, considering elements I want in the game and overlooking a bit of level design that should be enough to think about.

Enter technical choices.

Question: what free game framework support real time multiplayer, is performant and use pure HTML5? … none.

Partial answer, I love Phaser.io, so easy and fun to develop with. But 2 elements held me back at choosing it right away.

Biggest one was, how to sync multiple players on the same space? After all people should be seeing the same arrow flying and hitting the same stuff. When microseconds matter for accurate shots to happen, sync can’t be taken for granted. In fact there are many techniques online shooting games use that were not available out of the box for browser games. Even Websockets couldn’t support it as it’s based on  TCP, not UDP. WebRTC just came in years later.

So… Unity 3D? 😢

They do pack all i’d need for game design, asset management, physics, and i bet there is much more. There was a cost at the time to deploy at mobiles but it would deliver a much superior performance than something in HTML5.

But 3 factors drove me away:

  • vendor locking
  • no HTML5 deploy for browsers
  • considerable learning curve
  • real time networking (MMO) was still crawling

So specially for the networking implementation complexity i gave up on this lib.

I thought another of many other libs that use SVG or WebGL, so we could pack more interesting visual effects, but a decision was never made. Work took a huge space in my life, along with moving to new places and investing in more ‘social time’ something new for the geeky me.

🕛🕝🕞🕘🕙🕚🕐

Development Plan – proof of concept

Present day, present time: 2016-03-08 6PM. In between jobs is probably my most accurate status.

There is no time limit set for this project, nor I consider delivering consistently.

Current goal: rendering something that shoots something, and the scenario should sync for every player connected within 1 second. Ideally, the world state persist.

Pragmatically, the floor will be a flat plain and limited in length. The ‘archer’ spawn at a random position, it represents under control of a player while they are connected. It should be able to shoot a basic physical object, it goes off horizontally at the press of a button – so controls are reaaaally simple.

Architecture lowdown

Clients will run the all of game logic, it should as usual process inputs, events and send (ideally) deterministic information to the server. Almost all input is transmitted, but also the results (where arrow hits, what happened, etc).

The server would be pretty much ignorant of all game logic, not validating inputs / results but storing events and transmitting it to connected clients. When a client come to reconnect the server would send all events.

Needless to say, this is not a secure client-server architecture, it’s much more of a p2p. In traditional multiplayer architecture, the client acts as a vessel for input & rendering, while the server is in charge of processing action, events & results. Our case is simplified as proposed:

  • game spawn player 1 at randomly generated X/Y position (send event with position)
  • player 1 holds down button to shoot arrow (send event with position)
  • player 1 release arrow 1 (send event with angle, force, …)
  • arrow 1 hits the floor or enemy and become immovable (send position it hit)

All events should be sync in between clients as they arrive. Still unsure on how to fine sync certain things, like arrow trajectory.. some funky jitter may happen.

Tech choices:

The foundation laid made upon Phaser.io & Firebase for a 1st try.

Using Browserify + npm for managing packages.

Most likely deploying @ Heroku or GitHub Pages.

Unknowns and risks

¿Can firebase add any arbitrary data on server side, when it receives my json Object, and before re-transmitting it? I really need to set a timestamp when an event it arrives.

¿Can I really sync physics in such simplistic way?

¿Will the delay of Firebase events be acceptable? If not i could run some WebRTC solution on the side.

¿Is it going to work on mobile as is?

Wrapping up

Hope to deliver a first version soon, stay tuned!

 

 

Love you long time!

Love you long time!

For a long time I’ve forgotten the blog since I was busy with so many professional goals.

Has been crazy (awesome) 3 years since. I’ve followed my dream of working in startups in Canada, then to Chile and back home in Brazil. Time to take care of the body and figure out priorities in life.

Ok, no more blabla! I’ll be posting about what I intend to develop on hobby time. I personally love games and have a crush for social good, let’s enjoy what comes up 😃

JSONP with Express.js API – cross domain request

The problem:

So you have this awesome API endpoint, but of course it is another domain as the static site.

Web browsers are pretty moody with Cross Domain and there are actually very good security reasons for that, but even using good practices the old Internet Explorer don’t care.

Welcome ancient jsonp techniques!

Solution

For some Express.js API running on Node.js and client using jQuery (or something alike)

In your server:

app.get('/my-unique-endpoint', function(req, res, next) {
  var myAwesomeResource = ["hello", "mundo"];
  if (req.query && req.query.callback) {
    res.set({
      // nice to have, but Chrome dont seem to mind either way
      'Access-Control-Allow-Origin': '*',
      // right content type prevent warnings and errors
      'Content-Type': 'text/javascript; charset=UTF-8',
      // optional, this is in seconds, equivalent to 8h
      'Cache-Control': 'public, max-age=28800'
    });
    return res.send(200, "" + req.query.callback + "(" + JSON.stringify(myAwesomeResource) + ");");
  } else {
    return res.send(200, myAwesomeResource);
  }
});

In the client:

// see the data in your console
$.getJSON("http://myawesomewebsiteurl/my-unique-endpoint?callback=?", function(data){ console.log(data) } )

Caveats

jsonp is works for GET verb, because it effectively execute the code received as if it was downloading a script.
for the same as above, the source should also be fully trusted!

Loggly middleware for Express.js (server visibility)

Hi!

Oh how long without posting, I’ve been missing it dearly, but in transition between jobs I was super busy, and now I can take the time to add some cool stuff =)

Use Case

I’ve been building an API, it is very cool, but the visibility for it is naturally low compared to websites. Loggly offer a great service for monitoring servers via a simple API available in node.js. While this API is cool, it is super broad and require some experimentation to implement an adequate visibility level.

Wouldn’t be amazing to be able to see every request that come in your server and how it respond? Utopic? Absolutely possible!

Loggly API

Implementation

This implementation has been heavily inspired by Connect logger middleware – which is great.

I deeply recommend you to tune it for your visibility needs, though. Make good use: https://gist.github.com/flockonus/5380753

// suggested use:
app.configure(function() {
  app.set("port", process.env.PORT || 3005);
  app.use(logglyMiddleware);
  // ..
  app.use(express.bodyParser());
  app.use(app.router);
  // ..
});

Notes worth taking

  • This snippet will show you information in your console when o development
  • The info sent might be too much in terms of size or frequency, make good use of customization for your needs
  • If you are dealing with a website, I advice you to not send every path hit, it is just too much

Cheers!

2012 Recap

2012
Early this year.. I had a car, house all for myself on the weekends, a girlfriend, presence of family and friends, had maid once a week, a dog, cheap beer, worked with the tech I like the most and still was not nearly satisfied.

In Canada I live in a small room sharing apartment, am experimenting in new job, have to study, cook and clean for myself, smaller number of friends, no actual family nearby.

To summarize: All I have done was with support of friends and family, I am useless by myself. I can also say for sure that I am growing despite all uncertainties. Back then I had too much in my mouth, after a big cleanup I can see better and crave for more!

CarrierWave – limit file size (plus gif fix)

CarrierWave has an awesome abstraction API. It is simple, clear and extensible. But has some critical vulnerability specially when combined with image processing, such as, ImageMagick when resizing an image will consume exponencial memory size and any upload can easily make your process crash, when not processed safely. Also, it is not pretty good to combine .gif out of the box, because it makes a collection out of the file.

Friendly advice beforehand; Using http://filepicker.io/ may be a way better idea if you are hosting in Heroku, just make sure if fits your constraints before get hard work done.

Solution Spec

Hard limit file size of the request, so the process don’t block for too long, and don’t blow memory!

If you behind a server such as Apache or Nginx, you can impose a limit to the request size, and you should!

Unless you are in Heroku, and afaik, there is no way to do that, at least just yet. So yes, this can be a major security breach for Rails apps on Heroku.

Given a successful upload, pre-validate size.

The ‘official’ solution attempt to validate the size after the file have been processed. It doesn’t help, since when processing an image rather large (6Mb image consumed 2GB memory in my case) your process will be killed! Letting your website down for some time, and letting your users down as well.

For gifs, take only the first image (less memory consumption too)

When processing .gifs it seems to make a vertical frameset will all the images in the sequence, so it looks like a movie roll, which is not what most people want. Lets just extract the first frame.

Interestingly enough, I found that the processor is invoked for all frames in the .gif. (thanks debugger!)

Solution code

This code takes care the mentioned specs (except for the request size limit), and I think the great advantage is that it avoids opening a file as Image if it fails the size constraint. As well as being very efficient with gifs (only acting on the first frame).
It works on Heroku, with integration for S3, and should work on Amazon Cloud and other VPS.

The shortcome is about handling the exception which is a bit messy involving controller-side logic in a non-automated AR fashion.

Controller

  def create
    begin
    @post = Post.new(params[:post])
    rescue Exception => e
      if e.message == 'too large'
        redirect_to news_path(err: 'file')
      else
        raise e
      end
    end
   #...

uploader

# encoding: utf-8


class NewsUploader < CarrierWave::Uploader::Base

  include CarrierWave::RMagick

  include Sprockets::Helpers::RailsHelper
  include Sprockets::Helpers::IsolatedHelper


  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  def pre_limit file
    #require 'debugger'; debugger
    if file && file.size > 5.megabytes
      raise Exception.new("too large")
    end
    true
  end

  def only_first_frame
    manipulate! do |img|

      if img.mime_type.match /gif/
        if img.scene == 0
          img = img.cur_image #Magick::ImageList.new( img.base_filename )[0]
        else
          img = nil # avoid concat all frames
        end
      end
      img
    end
  end

  version :large, if: :pre_limit do
    process :only_first_frame
    process :convert => 'jpg'
    process :resize_to_limit => [1280, 1024]
  end

  # Create different versions of your uploaded files:
  version :small, if: :pre_limit do
    process :only_first_frame
    process :convert => 'jpg'
    process :resize_to_limit => [360, 360]
  end


  # For images you might use something like this:
  def extension_white_list
    %w(jpg jpeg gif png)
  end

end

Plenty of Fish – Lessons Learned

Just amazing talk! With founder Markus Frind a guy who made a dating website because he wanted to improve his CV with some .net experience. His website, Plenty of Fish went viral when the term wasn’t even appropriate for it yet! With over 200 signups a day, and millions of users in his database with all sort of breakdown information he is the solo owner in POF.com

His talk was mesmerizing and often funny as how casually he mentioned amazing achievements. At early stage, with such a low competition and network effect his product was so succesfull it wasn’t even funny.

Some highlights and inferences from his talk:

  • He never made a market research. He was the right man, at the right time, with the right attitude – trying to create a cool dynamic website.
  • Scaling was a huge barrier back then. Servers ran in his house, much like Facebook stories. Doesn’t existe anymore nowadays.
  • It is a prominent time for “growth hackers”. They are hiring phds from all industries with super developed skills in statistics and complex problem solving – cancer researchers, astro physicists (I can’t get my mind around that. Why not young people?)
  • Much more focus on retention than acquisition, probably due network effect and the nature of their service.
  • Always focusing on experimentation, throughout deploying and measuring. The man have a deep scientific soul. He admits not to use his own system but have put tons of effort into analyzing the metrics and the impact of the features.
  • Plan usually 1 month ahead, due how unpredictable changes take place feels like a waste to think too far ahead.
  • His advice: Just push it out of the door, don’t be afraid to crash at small percentage of your users, besides, if the service is good enough not much can make them just flee (apply with discretion, obviously)
  • 8 out of 10 feature implementations fail miserably. 1 achieves low results, 1 kind of make it well.
  • Even when entering other countries he admitted never to research culture, just experiment with development.
  • Operations efficiency is allegedly their competitive advantage, as he mention to use a infinite smaller amount of servers than competitors.
  • In one year period they’ve seen their traffic shift from +90% web to 70% mobile app. A trend that have taken Japan a couple of years ago.
  • Their strategy still focus broadening and developing the market, while mostly ignoring competition.
  • Still experimenting exponential growth. He says he doesn’t care for selling, in the end the money will go to himself as solo proprietor.
  • Somebody asked him if he would work with anything else, he said: “After his job working with anything else would be like watch grass growing”

Very glad I attended, intriguing and  inspiring session.