Tuesday, February 25, 2014

Model Loader Success

This past week (on thurs?) I finally got the ThreeJS Collada model loader to work.  Not that Mr Doob's model loader is hard to use, I'm just a newbie who had a hard time with a couple things.

First; deciding whether to use the JSON or Collada formats.  JSON is the preferred format of ThreeJS programmers importing Blender models, however, Collada is the default (nicely supported) Blender exporter so... I decided to with Collada because I'm an artist at heart.

Second; learning how to "bake/pack" my textures properly in Blender BEFORE exporting to ThreeJS.

Part two had been giving me no small amount of difficulty getting the texture maps to export to ThreeJS with the models.  The model part of the loader worked from the word "go" but the textures had eluded me for several weeks.

Sidenote:  the cool thing about the JSON format is that it turns your model into a .js file that you can open and manipulate vertices, animations, etc...   which has it's obvious advantages.

So with the models now in the game and dressed for success I am putting animation on the back burner.

I have a new set of issues to work through around the fact that the Collada loader seems to have difficulty loading several files.  The ColladaLoader object itself apparently only wants to load 1 super model (pun intended) that is then parsed into a "model array" (or insert your favorite data structure here).  Stack overflow has several great parser snippets with interesting work arounds for partitioning this super model DAE object.

Once I get a handle on parsing the super model it's a fairly simple matter to manipulate the individual models in 3D space with ThreeJS.

Oh, I also got the screen-panning working (standard to every RTS) with only a few kinks that are Javascript specific.  For instance, the keyboard input won't work until you "mouse click" in the canvas/browser window.  This confused me for about 10 solid minutes until trial and error eventually prevailed.

Aside from minor issues like that panning and such this week has been very successful.

Finally I also got some REALLY basic picking working which should help pave the way for getting the marquee selection working (standard group/area select for RTS).

To wrap up;  this past week I created the foundations for the screen movement, mouse picking/selecting, and asset loading.

With Zach's success in getting rudimentary message passing working we are now one step closer to piping our model and view/controller together.

Thanks for reading,
Clay Francisco

Saturday, February 15, 2014

Starting out with Javascript - "It's single threaded?"

This post is about the Javascript "game-loop" and passive event handling for game-state updates v.s. the traditional game-loop.

Ok, so lets get the things we know out of the way.

1) Games depend on hundreds/thousands of logical computations per second.
    Because we want games that are more and more realistic.  Or at the very least,
    feature rich.

2) Multiple threads help the CPU process information in parallel; faster.
    For instance; game logic that isn't UI dependent (like flying birds and grass
    animations) can be farmed out to separate threads.  These UI independent
    threads can update game-state whenever we want them to.

    It is kind of confusing to refer to these kind of updates as game-state though.
    If it doesn't affect player experience AT ALL (if it is purely visual), is it really game-state?
    I say "No" it is not.  It is "environment" state.  This kind of state should be kept separate
    from game logic for many reasons.  My favorite is it allows us to replace the entire environment
    outright.  Go modularity!  

    We must now remember that Javascript is NOT multi-threaded so we are cut off from this
    optimization.

3) Games need a Game-loop:
    ( Take Input -> Update Game-state -> Draw New Game-state)
     
        a) Take Input:
                   We have event handlers that listen for user input.  
                   These event handlers place update requests in an event queue.
                   Normally the updateGameState() loop "pops" this event queue
                   every time it fires off.  In javascript however, this is where we have a
                   second tier of listeners that make calls to requestAnimationFrame().
     
        b) Update Game-state:
                 Update functions validate user requests and execute appropriate state changes.
             **Hopefully I can explain this right...
               
                 In a traditional game loop you have a draw method that is called around, lets
                 say, 60fps and a logic update method that is called around 30x per sec.
                 The draw method will have some kind of smoothing effect like LERPing or
                 tweening to keep the animation from looking like a clock tick.

                 In our Scrounge World Model the logic engine's update is only called 10x per sec.
                 Which means we do 6 frames of smoothing per logical update.
             
                 **Remember:
                 Javascript isn't multi-threaded so we can't have this kind of "forced" update
                 loop.  This is partly because HTML doesn't support state-fulness.

                 I have to make you look up HTMLs state-less nature on your own as I am no
                 protocol expert.  However I can explain how this affects us and how we create our
                 Javascript equivalent.

                 The big difference in a Javascript game-loop is our updateGameState() method is
                 no longer a naive loop.  Instead we have a super EventListener() method that
                 passively listens for changes to game-state.

                 What this looks like on the outside:
                         function gameLoop(){
                                 updateGameState();
                                 drawNewGameState();
                                 requestAnimationFrame(gameLoop);
                         }
                         //get things started by calling the function
                         requestAnimationFrame(gameLoop);

                Which frankly isn't that far off from the traditional structure.
                But with two main differences:
                    1- the updateGameState method is passive     ...and...                  
                    2- requestAnimationFrame is in control of the game loop

                What this looks like on the inside:
                        function updateGameState(){
                                //updateGameState() just wraps all of the eventListeners for UI.
                             
                                mouseEventListeners();  //onclick, mouse over, etc.. would be wrapped in here
                                keyboardEventListeners();  //keypressed, keyup, keydown, etc...
                       }
               
                **Note: There is some "preventDefault()" method that has to be called within the
                              individual event listeners in order to prevent the regular browser functionality
                              from firing off that I don't really understand how to use yet.
                              Mainly, I need to figure out how to use the right mouse button and suppress
                              it's default function.

                If you know how to use Javascript DOM event listeners then handling UI should be
                fairly straight forward.

          c) Draw New Game-state:
                    Render the updated game-state to the screen.

                    The draw method is a wrapper method that resides within the game-loop and 
                    calls every game entity's own draw method for the given update type.  
                 
                    i.e.  The event handler X() fires off logic method BadguyOnCollision() which
                           will queue two methods when triggered:
                           whoDidIHit() and damageWhoIHit()  (or perhaps just itself but whatever). 

                           We "pop" the event queue as discussed previously and perform update.
                         
                           whoDidIHit() searches the entity tree to find the entities involved in the
                           collision and damageWhoIHit() performs the entity damage logic (my AC v.s.
                           your THAC0 anybody?) and updates the appropriate entity's life totals (the game-
                           state).

                          damageWhoIHit() calls the appropriate damage animations for the entities and
                          then requestAnimationFrame() decides when to render them to the screen.
                         

Hopefully this all made sense as it is still fresh and squishy in my own mind.  As these ideas start to solidify I may come back to these posts and clean them up and expand them if time permits.

Thanks for reading,
-Clay Francisco
                       





Thursday, February 13, 2014

Splitting up the blog

We decided it would be best if Zach and I each started reporting on our technical progression and not just outline the overall progress of the game.

I will still be keeping up on the overview updates in the Home thread but it has come to our attention people may be interested in the more nitty gritty details of the work we are doing.   This was of course the original intent of the blog but time and details slipped through my fingers and it became a snap shot of progress, not a catalog of experiences with implementations.

So the blog has been split into the three logical components.
    - Overview / Home (non-technical)
    - Model (Haskell language implementation details)
    - View and Controller (Javascript language implementation details)

That's pretty much it.  Hopefully you'll get the implementation details I know you're craving in the Javascript and Haskell threads and that we can keep you up to date with our overall progress in the Home thread.

Thanks for your continued reading.