2009-12-29

System Failure; Moustache is Clown

Bad News:


I suppose I need to pay more attention to my alien parasite; I think I forgot to pay it rent, and it decided to blast my sorry ass with disease; Nothing permanent, but in a certain high fever, severe headachey, painful bloody mess.

As a result, I can't make the trip for the new years party. Nor can I do much of anything, at least until this xenoform decides to give me my life back.

I hope you all have a great time, and bears x 100 or something.

Good News:

Uhhh... None for me, thanks!

2009-12-17

New Super Mario Bros

 So Curetis Siva hangs out and plays New Super Mario Bros for Nintendo's Wii.

The results are a Mystery Science Theater 3000 like hilarious dialogue, and a perfect example of why this game is so much fun:



2009-11-21

mingl - depth sorting order

Depth sorting is a traditional fix for a variety of problems;

However, it is a unsolvable problem. Consider that you have two long triangles, and you point the camera down the longest side of each. The triangles overlap; So if you draw one before the other, one triangle will depth clip the other, resulting in incorrect blending. The traditional fix is to draw with depth writing disabled, and then draw with color writing disabled. This can fix that special case, but causes other problems like highlights and odd depth clippings.

As a direct result, you generally need to draw all opaque objects first; Then perform the above method, which should correctly render the transparent polygons. however, as it may be obvious, you need a specialized structure to deal with being able to partition and sort your meshes by transparency.

This problem is not related to alpha clipping or depth fragment alpha, which is the problem of a semitransparent object occluding other geometry. In practice, it does well to solve this issue though.

Here is the difference between depth sorting and non depth sorting your objects; Notice there are still some errors, but the effect is minimal:



This effect is largely a matter of taste; And mingl is not responsible for how you draw, only for abstracting the graphics rendering hardware.

In a unrelated event; Any of you that know the Atari 2600 game "Adventure"? Well, you had better know about this hilarity: Adventure 2600 Reboot

Sound familiar? 

Yeah. But it's not like my version; and after playing  their version, I think I can one up this, so I'll try and make a "Adventure Remix" using my mingl / xcore system. The benefits, are it is something I like to make, as well as something people can probably enjoy messing with for a little bit. I'm just drawing and modeling, but I do not plan to clone or copy the game, instead I want to recreate the spirit of the game, and add my own little improvements. Plus, with my new toon hemi shader, it can look all sorts of shiny.

Til' later;

-Z

2009-11-17

mingl - progress updates

xcore / mingl is moving along quite well.

Operating on a basic create / destroy paradigm, with bind/unbind as the activation mechanism and load as the data send mechanism, it works well for abstracting graphics hardware and allowing for faster creation of intense graphics applications.

Here's a nonsense screenshot:



This is a vector field represented as moving transparent spheres that are depth sorted. The vector field is generated by 3 functions modulated together.

The shading is generated via vertex and fragment program. The meshes are using a VBO/IBO abstraction paradigm.

All is well. More later.

2009-11-06

DXT Texture compression

DXT image compression (also S3TC) allows you to save:

DXT1_RGB -> 1:8  RGB 565 4 level only
DXT1_RGBA -> 1:8  RGB 565 4 level and 1 bit alpha channel
DXT5_RGBA -> 1:4  RGB 565 4 level and 7 level alpha channel

As a result, for certain textures DXT can be used to compress images with reasonable loss of clarity.



Most importantly, within the DXT5 compression scheme, you still have 4x4 texel blocks interpolating between two color values. These color values are RGB565 (5 bits of red, 6 bits of gree, 5 bits of blue) and thus the green channel can be more precise. Also, the alpha channel has all 8 bits, but interpolates between 7 alpha values per texel. As a result, you can use DXT5 to store compressed normal maps by storing the x component in the green channel, and the y value in the alpha component. Then, in the shader, you can calculate the missing z value from assuming your normal map was actually normalized (x^2 + y^2 + z^2 = 1).

More updates later.
Z out.

2009-11-05

Cube Sphere

The Naiive implementation of making a Cube a Sphere is to make a cube, then select all verticies and "Mesh -> Transform -> To Sphere". This results in severe distortion along the principal axes, and a poor approximation of a sphere, as a result.

A more correct implementation is to notice that this is analogous to taking two planes centered at the origin, and rotating them n time in discrete angular intervals, thus chopping space into uniform areas, resulting in far less distortion.

Neither approach is perfect because you cannot comb a hairy sphere smooth. But the Cube Sphere is far superior, and easier to generate using a difference equation.



Cube Spheres are good for working with planets and large scale data, but don't have many other uses besides easier texturing of spheres.

..I can;t seem to figure out how to post data to blogger... how to post a .py script?

It's not 100% perfect; copy paste into notepad or something

Here goes nothin':

#!BPY
"""
Name: 'CubeSphere'
Blender: 249
Group: 'AddMesh'
Tooltip: 'Creates a Cube Map sphere'
"""
__author__ = "Izcalli64"
__url__ = ("blender", "http://imaginaryz.blogspot.com");
__version__ = "0.0 2009-11-05"

import Blender
import math;

def generate_grid( ndiv, spanning ):

    #
    #Optimal spanning value: Unknown
    #Optimal spanning equation: Unknown
    #

    radius = 1.0;    #Fixed; don't vary this.
    points = [];
    ndiv = int( ndiv );
   
    #From experiment; It looks like you need a transformation from radial space to manhatten space:
    #
    #the only fixed points are the 4 corner points, from which there are lateral and vertical lines;
    #These lines must have points distributed on them evenly, by angle.
    #These lines are NOT consistent, but do consist of great circle arcs.
    #
    #SOLUTION:
    #
    #Generate a cube sphere by taking 2 lists of evenly distributed angles;
    #Generate the great circle planes (planes) that intersect the angles;
    #Calculate all points on the grid that are the intersections of both:
    #    The sphere of radius R
    #    Great circles A and B (will always form a line, no matter what.
    #The result:
    #    Quite a substantial amount less error than the other method. (see .blend)
    #The problem:
    #    Hard to optimize
    #
    dtr = math.pi/180.0;
    mina = 45.0 * dtr;    #Minimum angle (45 = pi/4)
    maxa = 135.0 * dtr;    #Maximum angle (135 = 3*pi/4)
    rangea = maxa - mina;
    dela = (maxa - mina)/float(ndiv-1);
    spanrange = dela * spanning;

    #Generate strip angles (for consistency)
    stripa = [];
   
    stripa.append( [ mina, math.sin(mina), math.cos(mina) ] );
    idex = 1;
    ia = mina + dela;
    while( idex < (ndiv-1) ):

        #Default angles (angular evenness)
        #stripa.append( [ ia, math.sin(ia), math.cos(ia) ] );

        #Corrected angles:
        delv = 2.0 * ((float(idex)/float(ndiv-1)) - 0.5);    #-1.0..1.0 range
        dels = 0;
        if( delv < 0 ):
            dels = -1.0;
        elif( delv > 0 ):
            dels = 1.0;       
           
        #Correction quadratic equation (B-spline could be more effective)
        #ian = dels * (delv*delv) * spanrange + ia;
        #ian = -dels * (1.0 - (delv*delv)) * spanrange + ia;
        ian = -dels * (1.0 - abs(delv)) * spanrange + ia;#Very simple; linear. Problem is not linear.

       
       
        #print delv, dels, -dels * (1.0 - (delv*delv));
       
        stripa.append( [ ian, math.sin(ian), math.cos(ian) ] );

        ia += dela;
        idex += 1;
    stripa.append( [ maxa, math.sin(maxa), math.cos(maxa) ] );
   
    for ex in stripa:
        print ex;
   
    #Generate strips:
    iy = 0;
    while( iy < ndiv ):
        ix = 0;
        while( ix < ndiv ):
       
            #Plane X / Circle X
            PXx = stripa[ix][2];    #cos(x)
            PXy = stripa[ix][1];    #sin(x)
            PXz = 0;
           
            #Plane Y / Circle Y
            PYx = stripa[iy][2];    #cos(y)
            PYy = 0;
            PYz = stripa[iy][1];    #sin(y)
           
            #Cross product (direction vector to use; can be optimized:)
            #nx = PXy * PYz - PXz * PYy;
            #ny = PXz * PYx - PXx * PYz;
            #nz = PXx * PYy - PXy * PYx;
            nx =   PXy * PYz;
            ny = - PXx * PYz;    #Optimized cross product from zero factors
            nz = - PXy * PYx;
           
            #Normalize direction vector
            nm = math.sqrt( nx*nx + ny*ny + nz*nz );
            nx /= nm;
            ny /= nm;
            nz /= nm;

            #Apply scaling of shape
            tx = radius * nx;
            ty = radius * ny;
            tz = radius * nz;

            points.append( [tx,ty,tz] );
           
            ix += 1;
        iy += 1;
       
    return points;
   
def generate_points_swizzle( points, comp0, comp1, comp2, neg0, neg1, neg2 ):

    newpoints = [];
   
    sw0 = comp0;
    sw1 = comp1;
    sw2 = comp2;
   
    for P in points:
   
        np = [0,0,0];#[ P[sw0], P[sw1], P[sw2] ];
        if( neg0 != 0 ):
            np[0] = -P[sw0];
        else:
            np[0] = P[sw0];
           
        if( neg1 != 0 ):
            np[1] = -P[sw1];
        else:
            np[1] = P[sw1];
           
        if( neg2 != 0 ):
            np[2] = -P[sw2];
        else:
            np[2] = P[sw2];
        newpoints.append( np );
       
    return newpoints;
   
def generate_grid_uv( xdiv, ydiv ):

    uvs = [];
    iy = 0;
    while( iy < (ydiv) ):
        ix = 0;
        while( ix < (xdiv) ):

            u0 = float( ix ) / float(xdiv-1);
            v0 = float( iy ) / float(ydiv-1);
           
            uvs.append( [u0,v0] );

            ix += 1;
        iy += 1;
       
    return uvs;

def generate_grid_facelist( xdiv, ydiv, offset_index ):

    faces = [];

    iy = 0;
    while( iy < (ydiv-1) ):
        ix = 0;
        while( ix < (xdiv-1) ):

            fxy00 = int(offset_index + ix + (iy * xdiv));
            fxy10 = int(offset_index + ix + 1 + (iy * xdiv));
            fxy01 = int(offset_index + ix + ((iy + 1) * xdiv));
            fxy11 = int(offset_index + ix + 1 + ((iy + 1) * xdiv));
       
            faces.append( [fxy00,fxy10,fxy11,fxy01] );

            ix += 1;
        iy += 1;
       
    return faces;

def generate_cubesphere( in_radius, in_divisions, in_evenness ):

    #Generate each cube face, simply rotate it's data to match what we want.
    ndiv = in_divisions + 2;
   
    faces = [];
    points = [];
    uvs = [];
    origpoints = generate_grid( ndiv, in_evenness );#x,y,z
   
    faces.extend( generate_grid_facelist( ndiv, ndiv, 0 ) );
    points.extend( origpoints );
    uvs.extend( generate_grid_uv( ndiv, ndiv ) );

    faces.extend( generate_grid_facelist( ndiv, ndiv, len(points) ) );
    points.extend( generate_points_swizzle( origpoints, 2,1,0, 0,0,0 ) );    #x,y,z => z,y,x
    uvs.extend( generate_grid_uv( ndiv, ndiv ) );
   
    faces.extend( generate_grid_facelist( ndiv, ndiv, len(points) ) );
    points.extend( generate_points_swizzle( origpoints, 2,0,1, 0,0,0 ) );    #x,y,z => x,z,y
    uvs.extend( generate_grid_uv( ndiv, ndiv ) );

    faces.extend( generate_grid_facelist( ndiv, ndiv, len(points) ) );
    points.extend( generate_points_swizzle( origpoints, 0,1,2, 1,1,1 ) );    #x,y,z => -x,-y,-z
    uvs.extend( generate_grid_uv( ndiv, ndiv ) );
   
    faces.extend( generate_grid_facelist( ndiv, ndiv, len(points) ) );
    points.extend( generate_points_swizzle( origpoints, 2,1,0, 1,1,1 ) );    #x,y,z => -z,-y,-x
    uvs.extend( generate_grid_uv( ndiv, ndiv ) );
   
    faces.extend( generate_grid_facelist( ndiv, ndiv, len(points) ) );
    points.extend( generate_points_swizzle( origpoints, 2,0,1, 1,1,1 ) );    #x,y,z => -x,-z,-y
    uvs.extend( generate_grid_uv( ndiv, ndiv ) );
   
    #Scale all points by radius value (lol?)

    return points,uvs,faces;
   
def main():
    Draw = Blender.Draw
    PREF_RADIUS = Draw.Create(1.0)        #"Radius" of cube-sphere
    PREF_DIVISIONS = Draw.Create(7)    #Divisions per face
    PREF_EVENNESS = Draw.Create(0.0)    #Evenness of point distribution (by area weighting, so uv texture distortion is absolute minimal at default value)

    if not Draw.PupBlock('Add CubeSphere', [\
    ('Radius:', PREF_RADIUS,  0.01, 100.0, 'Radius for the main ring of the torus'),\
    ('Divisions:', PREF_DIVISIONS,  0, 256, 'Number of subdivisions to generate'),\
    ('Evenness:', PREF_EVENNESS,  -1.0, 1.0, 'Evenness scaling for evaluation'),\
    ]):
        return;
       
    verts, uvs, faces = generate_cubesphere( PREF_RADIUS.val, PREF_DIVISIONS.val, PREF_EVENNESS.val );
   
    #Every vertex has an exact and corresponding uv value to it (sticky uv)
    #As a result, it shall be simple to assign face UV's.

    meshobj = Blender.Object.New( 'Mesh', 'CubeSphere' );
    meshdata = Blender.Mesh.New();
   
    meshdata.verts.extend(verts);
    meshdata.faces.extend(faces);
   
    #Apply uv coordinates:
    meshdata.addUVLayer("CubeMap");
    meshdata.activeUVLayer = "CubeMap";

    if( meshdata.faceUV ):
        for f in meshdata.faces:
       
            vinds = [];
            for v in f.verts:
                vinds.append( v.index );
               
            vdin = 0;
            for vdex in f.uv:
                uvd = uvs[ vinds[ vdin ] ];
                vdex[0] = uvd[0];
                vdex[1] = uvd[1];
                vdin += 1;
       
    else:
        print "#ERROR; Face UV could not be enabled??";
   
    meshdata.calcNormals();
    meshdata.update();
   
    meshobj.link( meshdata );
    Blender.Scene.GetCurrent().objects.link( meshobj );    #Is this deprecated? #ERROR
   
main();
#Blender.Draw.PupMenu("Error%t|This script requires a full python installation")

2009-10-31

Vertex Buffer Objects - speed testing

For drawing 32,768 meshes of 12*16*2 triangles each (1 triangle strip):

OpenGL 2.1 hardware:
VA/IA: ~230ms
VBO: ~30ms

OpenGL 1.4 hardware:
VA/IA: ~230ms
VBO: ~240ms

The note is, although your card may say it supports the VBO extension, or support VBO as per the OpenGL 1.5 specs, it doesn't.

VBO's only work in 1.5 GL's or later, due to hardware restrictions.

Remember; If you worry about optimization, you'd better have timing tests to verify that it even matters. Saving about 10% or more is useful.
Also, small frame optimizations are useless; Anyone can do those, and they generally introduce unmaintainable hacks. Worry about your high level optimizations, like using "most common failed test first" and algorithmic and design changes to maximize your logical speed.

Anyways. Here's a buncha UV spheres, as mentioned (generated using xcore + mingl):



Currently working on the texture functions in mingl. Having to write compressors/decompressors for all the DXT formats. It'll be quite useful though.

Z out. Happy Halloween.

2009-10-29

xcode, mingl, xgfx

Continuing my great adventure to construct the engine I need;
Yes Unity is now free. Who cares; What we need is a blender Synthesis program so I can use all my high def animations and levels.

xcore is moving along nicely, most data structure and memory alignment things work perfectly. Still some issues with float hacks.

mingl is quickly being put together, the abstraction of all mesh data into the VBO/IBO/VAO paradigm makes using OpenGL very very nice. In fact, learning a mingl type system is far easier than learning OpenGL fixed pipeline crap.

Vertex Buffer Objects:

They don't help unless you have OpenGL 1.5 or higher. Go figure.
And instancing doesn't really help unless you have a very specialized, small geometry item.
Here's 32,768 cubes:



If you stare too long, you begin to see a n-dimensional triangulation or worse, a shadow of a n-dimensional object.

I'll press on until I can have dancing lizard demo # 4. Or in this case, it might be a higher res female model.

Peace out.
-Z

2009-10-25

xcore, mingl, xgfx

Not much to update today; Started some new projects.

In the spirit of the IGTL::Sys classes I made (mostly copy paste from them since they're so dang useful), I am building xcore, which is responsible for:

1. OS level byte types
2. exceptions and error reporting
3. CPU identification, SSE intrinsic math and special instructions
4. Memory manager
5. Specialized templated common file structures, like index_array, carray, index_deque, string_table
6. Directory I/O and file I/O

XCore is the minimal utility toolkit that drives all of my programming. On top of XCore is an important layer called GHOST, which was coded by the blender foundation and furthur extended by me for my own projects. GHOST is a cross platform windowing toolkit that accomplishes some of these things, but not all of them. I'm using it religiously since it avoids stupid SDL licensing issues, and has support for context sharing, multiple windows, and a better event system. The nice thing is, since I use blender anyways to make all of my media, it'll be a cinch to always mention i am using code from blender, thus keeping in line with their license for distribution.

mingl is a minimum wrapper on top of OpenGL that completly abstracts it, preventing me from making any non-suppported OpenGL calls. For example, it wraps all geometry data as a vbo/ibo/vao class (read up on OpenGL 3.0 if you don't know what these are) and internally can down-support any openGL version using this system. It cannot abstract shades really well, so it looks like it will require GL 2.0+ for any shaders to even work. I'm also not sure yet if I need to write my own shader coders so that the engine can generate shaders for vertex/fragment program aas well as GLSL; This seems a little difficult at the moment so I'll defer it.

xgfx is the graphics engine that performs culling, scene management, mesh updating, keyframing, armature animations, lighting, shadowing, and all the regular crap you expect to have in a game engine.

So, with this toolchain of xcore/ mingl/ xgfx /xoal/ xnet, it should abstract all the things I need for any game, just like I did back in late 2005. Except this time, it'll be my engine with no rules and no hangups or lies to slow me down. Of other importance, it's all using C++ as much as possible, so each component should be independent as much as possible.

Z out.

2009-10-10

KDTrees and blender gui synthetics

Remember kids, if you use a synthetic oil, it's not a good idea to switch back to regular.



As far as I understand it, "KDTrees" are simply a data structure that says:

def kdtree:
def node:
x,y,w,h
split
low_node *
high_node *
parent *
direction

And, each node occupies a region of space defined by a x,y,w,h box (or x,y,z) and "splits" that box into TWO boxes, along only one of the axes (either x or y). This way, you can more efficiently partition static objects into a scene; this is like all BSP / octree scene management techniques; However, updating a KD tree is rather expensive, it really is good for storing static scenes though as it requires a far lesser node density and can expand into any other volume as needed.

So, they're used in blender's GUI; I'm getting my mockup GUI system to work slowly, and here are many panels defined by glViewports with text in them. The text system is nothing more than a badass texture font I used some free program to generate with 2 px padding and as a alpha only texture, so the memory required for those letters is quite minimal; although fonts are not conducive to mipmapping, so you must manually provide other LOD fonts for your program. Don't forget that always mipmapping is better for your hardware.



I'm also perfecting my cMesh class, which will provide a full next generation mesh including armature animation and animux system, basically equaling and exceeding the capabilities of all existing high definition games; And doing so in a manner consistent with next gen technology (VBO/Shader) while still retaining the ability to be processed via older cards, at great CPU expense.

It looks something like this:



The concept is present in all games I have hacked, and works like this:

A mesh consists of "tiles", which are separate VA/IA's that contain some amount of triangle strips/triangles/quadstrips with a consistent vertex format and ideally contiguous data. This means each tile can store different vertex parameters, the usual culprits are:

current vertex position (3)
next vertex position + weight (4) //For mesh keyframes only
texcoord 0 (2) //1st texture coordinate
texcoord 1 (2) //2nd texture coordinate (if you have seperate UV mappings, not efficient)
normal (3) //Required for any lighting
binormal (3) //can be shader generated, but space may need to exist in VA array)
matrix indicies (4) //Required to skin a mesh that has more than 1 matrix deforming it
matrix weights (4) //Required to skin a mesh properly

So, each tile can behave as a independent mesh. Above a tile is a tile state, which contains the RC (RenderCommand) array for actually issuing the stripping indicies and material changes and matrix palette updates for this mesh.

Above that is the TileTree, so you can swap/zsort/prioritize and use lod tiles as needed.

the concept of a tile is to load all mesh data into your graphic card, and then merely tell the card what to use to render via a few array binding commands. This is extremely efficient, as it supports mesh instancing to a large degree, and prevents transferring data to the card. The only drawback is you still have to transmit matrix updates to the card, but even a 270 bone character (like Valgirt) this is still far less information that a small VA.

So, once you have tiles setup, we have a generic bone/matrix animation system, with a matrix class (yes, I like quat's too, but matrices require less conversions in a game setting; these matricies can be changed to be only state driven mind you.).

The heart of this system is the base animation classes, which consist of "Keys" which are blocks of static data to interpolate between, "Channels" which are a list of keys and times, and "Animations" which combine channels together to form complete animations.

The Animux is a animation multiplexer, which combines any number of animations together, so that you can use multiple types of animations together, for instance "Run_legs" and "Shoot_Torso" like Quake, or "Face_Phoneme_ma" and "Run". This allows you to make characters that can walk, talk, and run + shoot at the same time, and even use IK calculations as you want.

I've probably done this thrice before, but THIS time, I've got it nailed, and have massive amounts of evidence and experience with the new GLSL to support this type of design. Hopefully, I can get AniStar up and running so I can actually have a program that can make animations for given characters.

Z out.

2009-10-01

Graphical 'Lag' Problem resolved

Here's the problem:

You code up a nice 3D game, and find that every time you call 'swapBuffers' your program is blocked from execution. You've tried threads, weird API's, and even low level OS hacking tricks; And nothing fixes it! Your game will still be forced to run at 60 FPS, no matter what, and every buffer swap lags your code at least 15 ms! Which is total burned CPU! And tons of dropped packets! And messages!

If you happen to have a graphics card, and specifically a NVidia one, here is the problem:

Go to start->Control Panel-> NVidia Control Panel(Display; Move to the display tab, advanced... Open the Nvidia Control Panel)

Make sure this is off:



What is happening, is it is making a crit section/thread safe block for buffer swaps, which if you write high performance games, this kills your testing phase since your game is force-lagged out.

This easily pushed my FPS and IFPS from 60 to well in the hundreds. In fact, in my GHOST test, I went from 15 RFms with 1 dropped frame to 10 RFms with 0 dropped frames. This translates to 0 dropped frames per second from 60 dropped frames per second.

I have fought this problem for a while; glad it wasn't my problem. The moral of the story? Sometimes you just have to step back and learn something new.

- Imaginary Z

2009-09-29

Dream Blog - Fuckin' Midna

Not much to describe; A lot of it was fuzzy, and some parts were pure fanservice to me; Of which I will not include. If they weren't obvious, too bad.

Apparently, John, Brien, and I were driving away from some upper eastern state; I guess something happened and we had to get out of there. So it's a roadtrip dream for a while, that is until we come across a bridge made out of pretty rickety stuff, something noone would ever drive a car over. Well, turned out we couldn't drive the car over it, so we hitched up and carried our stuff over to the other side; The area was extremely densely wooded, very large tall old trees, and we could see a motel not too far away. I kidded, and since I knew it was a dream, was like "Oh man, guess we can't get across." John pointed out that the floating logs in the mire below could be used as a bridge, but not seriously. Again, since I had control at this point, I just jumped down onto the logs, a good 30-50 ft fall into a alligator and log filled pit. Much to my surprise, the gator's had no intent of attacking anything, and I just walked across to the land while brien and john walked down a cliff calling me an idiot. I got bored, so I pissed off a gator intentionally just to see what it would do; It didn't do anything* except hiss. Oh well.
Anyways, we walked to the hotel through some foresty path, which was a little rundown, apparently everything had been abandoned like some sort of zombie apocalypse dream. Though, there were no other people around John did have a .45 like sidearm, which was nice, brien was just brien, and I didn't have any weapons. We went it, the place still had power, and set up camp on a higher floor, the water as a little murky so we'd have to move forward eventually; But with power we could survive a little bit. Somehow, Zach was able to join us, and we chatted it up, he seemed to know more about what was happening, but it was all cryptic and didn't make any sense.
Somehow there's a memory gap here, and we're entering this city which had been mostly abandoned, this odd side plot of this little Midna clone chick constantly thwarting our adventures came clear; It was like a little demon, exactly like Midna. Apparently it had the hots for John or something, but it was trying to kill us as we went through the city to the center or somewhere like that.
Well, since it's entirely fantasy at this point, I can't clearly remember how it ended up this way, but Midna became our friend, and it turned out that this other demon was following John, because he had a pure heart, and only once two pure hearts could combine could she attain "ultimate power". Well, Midna happened to have one, and at some point John and Midna realized this; Demon shows up, takes the pure heart (which, I liked this detail that the "pure heart" was purely glitter; It had no effect being added or removed to either person) and morphs into this giant cobra-shiva-rampage monster, and begins trying to kill John and Midna.
At this point it get's interesting, because we get a lives counter* and a equipment list, and start trying to fight off a rampaging beast. Of course it summons multiple other beasts to help it wreck up the place; all cool looking and somewhat reminiscent of "Inhumanoids". But my dad, dad's brother, and plenty of other familairs showed up, each with special abilities to help us construct traps to try and kill the beasts. Dad's bro (also named John) was a demolitions expert in a lab coat with welding goggles and gloves, and we used him the most because we could lure the monster to a building rigged to explode, and do some serious damage to it
So we continued running and crazy climbing things trying to stop or otherwise kill the monsters, John and Midna equipped ethereal weapons and constantly were moving and firing green glowing arrows at it like Hexen; I dunno what happened to everyone else.
At some point, we got cornered by all 4 monsters, and the large one declared victory, but somehow there was a blackout and explosion, and everything went black.
After awakening, the entire city was destroyed, it was very dark, the sky has a dark reddish tint and smelled of death, lights were barely glowing, and kelly, me and brien were the only ones nearby. I picked up a steel pipe and kelly had a crossbow and brien had a rock for bashing popo's with. Anyways, apparently, the world had ended and those monsters had completely destroyed civilization as we know it, which was great, given what's going on at the moment.
Ran into a stupid chain gang, rummaging through a car, I queried them for info, fought them, won easily (apparently, knowledge of martial arts went away too) and they told us the scoop and let us join their gang. Which included running around stealing things out of cars. So, then we began the quest rummaging through this destroyed world to find our friends.

Alarm goes off!

* Missing gross details only I care about

2009-09-28

Dream blog - New Mexico Bones?

Odd New Mexico Dream

WEll, not like my usual ones that are action oriented with a lot of violence, killing, and superpowerful weaponry. this one had a much stronger emotional feel, touching on some complex areas.

I don't remember how it really began, but a lot of familiar faces from the Palace showed up, and apparently we were somewhere in New Mexico for a festival of some kind. It seemed to be a wine deal, yet there were plenty of activities for the families to participate in, such as rail-carts, carnival games and the regular fair businesses. The palace guys all split up, and I remember messing around with skee ball and some other generic novelties before we met up for some authentic New Mexico chile in the food court. Times were pretty normal seeming, plenty of razzing and videogame discussions.
What was odd though, was that the camera and point of view would be switching from first to third person frequently, and there were two odd characters dressed in 1800 style pinstripe suits and black tophats, looking exactly like corporate fat villians, complete with monocle, white stache and that smug grimace associated with so much pork. Apparently these two kept having heated discussions on some topic, but only appeared in the background as whoever was filming was pretending to be a art student and making really nice framed shots of multiple things at once for a good composition in film.
Anyways, eventually we all got up to this little stadium deal for the rail karts, which was a short series of solid steel tubing and carts that sat on them, just like any old toy rail cars you have seen; Except these were ridable, and people were taking races on them (4 at once could compete) but generally the lightest person would win.
So, after watching them talk about this for a while, I went on the kart thing and so did amanda, we raced, but the jerk giving us the start cue made me lose a lot of time by declaring start before I was even in the cart. But I caught up, popping wheelies on the rails to gain speed coming down hills. But I slowed and let her win; Was pretty fun to have a lot of people cheering for a rigged event.
The camera was also noticing the two tophatters in the front row, constantly speaking to eachother about something that was getting noticeably more grim, people overhearing their conversation looking worried and confused at the pair. Cue montage; And as the camera goes to listen to their conversation and I was dismounting the kart, we see a zoom out of New Mexico and a small story unfolds.
Apparently, there were gold mines in new mexico at some point; And the man on the left (Chesterfield? I can;t remember his name) had been a descendant of the family that founded one of the mines; Now the mines lay in secrecy so that the US government could not track the gold incoming and would basically be a black market deal; The business was run successfully up until Chesters era; His father had always explained that one of the mines was never to be investigated or opened; and declared that any man found entering or exploring the area would be killed on sight. But he explained that he and a buddy snuck up there, assuming that it was to hide the largest gold deposit; And they snuck up there near dusk, and upon entering this small hole in the ground, they saw a extremely heavily boarded and partially caved in mine with no markings at all, and a large supposedly tool shed on the right, the roof was covered in dirt so as to be invisible to aerial spies. Though, the damn fools decided to open the shed in hopes of discovering more about the hidden gold stash.
Well, far be it from my dreams to exclude the paranormal, but inside was a fully assembled dragon skeleton. As stupid and generic as that sounds, it wasn't the fact that a perfectly assembled set of bleached bones was there, or that it looked very menacing, or even that it was a generically creepy setting; There was a completely different feeling, similar to the kind that you get when you know someone is watching you; When you feel a spiderweb drape across your neck even though you weren't moving; And especially that horrible sensation you immediately get when you know something is very very wrong and your life is in grave danger; both boys were not scared; This wasn't anything to be afraid of, yet they instantly whitened from fear. The camera did a nice pano-zoom behind them, and this eerie noise began to creep in as the two freaked out and slammed the shed shut, forgetting to place the lock back on the doors. The noise sounded like the whispers and moans of a thousand dying people, including children.
Snap back to present day times, the two continuing their conversation. However, as I was chatting it up and helping someone's kid get on the go-kart, you could overhear Chester say something to the effect of ìand I'd never seen so much gold in my life!î The other man nods, but immediately everyone in the crowd got that feeling again, looking up and around wondering what was happening and why everyone suddenly got chills.
Without any warning, this deep growly voice emanates from the ground as a large skeleton dragon claw emerges, and pulls up (you obviously guessed it) that same dragon skeleton; with a few aesthetic differences. Mainly, instead of bleached white bones, they were slightly yellow, some with reddish strips in them as if the creature was rebuilding it's body piece by pieces. If you are familiar with the concept of ìlichî think that. It screamed at the men, lifting and staring down the two yelling multiple things in multiple voices, something no living creature can do; ìThat is MY GOLDî ìYou traitors killed your father!î ìlying sleaze bags!î and other random pitched sounds, but the primary voice was well understood. The men got up and both pulled regular saturday specials and fired round after round in to the skull; to no effect.
I, meanwhile, was rapidly moving to scoot the kids away from the rails, but they kept screaming like everyone else. I managed to shuffle them to safety as everyone else seemed to run away. I looked at this monster and arrogantly figured I could take this; Wouldn't be the first dragon skeleton I killed. Well, ìkilledî meaning broken. Just before the beast was about to rend the two to ribbons via claw swipe, I grabbed a rock and baseball bat and hit the rock into it to get it's attention.
Whooops.
It turned to glare on me, full force of it's psychological pressure bearing down on me; But luckily, since I had meet the real ìsatanî face to face before, this was peanuts. I stood there and yelled some generics at it to make myself feel better. ìLeave us alone! Go away!î I felt pretty good about the situation, I had plenty of space to run around in, and a weapon, and this thing was made of brittle bones. If I could get a strike in I'd be okay.
But, the creature was a tad more powerful than your average physical entity; I guess the fact it was a living skeleton should have queued me in on that. IT looked at me, then looked at it's target getting away, then smiled, looking at me again and began to try and crush my spirit. ìYou would lose your own life to save such evil men? You truly are a fool...î It leaned down, and reached out for me. So I bashed one of it's complex wrist bones with the bat, jumping out of the way. It reacted like I had hurt it's wrist, and looked at me again as I retorted. ìIt doesn't matter who, as long as they're people I'll do my best!î
the dragon looked at me with a quizzical, yet mocking glance, smirking as it leaned down and folded it's arms, still mostly in the ground at this point; Stared directly at me, hollow eye sockets suddenly aglow with a dim orangy red light. ìDo your worst.î
I Ran in, and bashed it's skull as hard as I could. The shock rang through my wrist like hitting a concrete pillar, and I knew I was good as dead. The thing didn't even move, no flinch, no crack... and from personal experiments, I know that that hit is good enough to show damage on any material I had ever encountered. But this didn't show any at all... nothing moved. I backed up, and the dragon began pulling itself out of the ground slowly, showing that it was a complete skeleton. I lost it at this point, and began rapidly hitting it's head over and over, backing up, trying to do something to stop it; but it kept it's skull low, and continued glaring at me as I began to run out of ground, it's newly extracted tail whipping about like Ridley's, smashing up the bleachers and rail karts; which had surprisingly been untouched the whole time; I guess whoever made the movie set wasn't sure how long these scenes would take.
I didn't drop the bat, but the dragon finally stood on all fours and shook some dirt off, it had some pieces of flesh clinging to it's thighs and waist, but not much. Oddly, the flesh was complete, not rotting or in disrepair at all, as if it was a complete being that was simply ìnot all hereî. It looked at me with a neutral expression, declaring ìI want your spiritî before snatching a claw at me, which I expertly dodged via a low roll; though, I guess it had other powers because it's other hand came out of the ground and got me.
After being yanked under the ground and back to the surface, which hurt like hell, getting indian burns on your neck, legs, and scalp; it held me in front of it's face, I struggled to get out of it;s grip, but it held on correctly; Just enough to barely suffocate me, not enough to kill me. I wasn't sure at this point what it was trying to do, but I had a strange feeling it wasn't intending to flay me quite yet; Why I wasn't sure, I tried to hurt it, but with zero success. And those bastards that caused this ran away, the chickenshits. I could see police officers running out with shotguns to start blasting this thing, but I doubt they understood what the people were screaming about.
Anyways, without any real warning, the thing opened it's jaws and lowered me legs first into nothing; I mean, it's a goddamn skull, we've all seen the classic ìskeleton drinks wineî gag right? Well, turns out something like this isn't exactly the same, and to my own horror, it had a complete body internally, I could see it but only from certain angles, as if it's outwardly transparent body had disguised it's organs and real muscular tissue.

This part gets a little... squishy, so if you don't want to know, don't continue.

I'm not one to be unfamiliar with dragon gullets; and being swallowed alive and whole was at least thankful, minus the fact that in reality this would be one of the most horrible deaths conceivable; Asphyxiation with an acid bath + being rubbed with grinding stones. Sounds great, right? Fuck people who enjoy that. I hate em. But, lucky for me, as I tried my damndest to escape, but with obviously no success, everything kind of faded out, as if some sort of static field was creeping up my body, eliminating random pieces of existence one at a time. Luckily no pain was perceived, but being dissolved like that instantaneously is rather frightening. And not fun at all.

Well, maybe this part was not squishy. That's ìVore Liteî for ya.

The camera at this point looked as the police began to shoot at the skeleton, doing nothing of course; And the monster obliged them by spitting out my clothes onto the bleachers, which contained my ID and other information they could use to confirm who was lost. The monster then sank into the dirt again, slithering back to where it came, leaving the crowd with a odd event to sort out.
Fast forward to some time later, apparently my funeral was had at the edge of some lake somewhere, there were a lot of people cause my family loves to use family events as excuses to hang out; More power to em.
But, after doing a generic sad walk showing my folks and sister discussing my death, the two men with hats approached them and had a conversation. Skip forward to a large laboratory, in Area 51 style where some scientists were trying to summon that demon; Which is stupid, why would you need to summon it if you knew where it was? Obviously it wasn't going to rest until it's gold hoard was complete again. Jeese, what a stupid cast. Either way, I wasn't dead, I guess the creature could see through people just as good as it could totally destroy people. It's a little hard to explain, but it ìsharedî it's existence with me, basically absorbing the essence of what I was including my physical state and other attributes; Much like Raesir can do, only not as good. So, it and I had a lot of talks, and I grew to respect this demon; It had a lot of personality and stories to share; It led quite a sad life, something like Snake from MGS.
Anyways, we kinda ghosted up to the lab to watch and make fun of these losers trying to understand something they can't, simply because they didn't have enough materials to make a judgment call on what to do. Science always works because of the repeatability and applicability of tests; That's why you can trust it; You can prove a lot about gravity anywhere on the earth, just as you can basic newtonian physics. The more we know the more we are allowed to construct new hypothesis and test them. But anyways, being a part of another organism is kinda like being a satellite for a spaceship in a video game; You don't really get to leave ever, but you do get to hover around your owner. It also turned out that every single person that this dragon had eaten during it's lifetime was inside it, so there was a plentiful hoard of people there, that spoke some language I couldn't understand well at all, but eventually could figure out. Kinda 13th Warrior-ish.
So, we watched them try and built a primitive particle accelerator in order to create a channel for the thing to appear in. I suggested to the dragon that we should make it electrocute that fat guy, but he declined. He would get his dues, that tophat motherfucker. But it did let me go over and whisper at my folks this was bullshit and they should leave asap. Maybe Kelly is right, and ghost powers are awesome...

Alarm goes off. Groggily wake up, glad to be alive again.

Of curious note was the overlay of the map of new mexico; I need to draw it and figure out where it was located; If it does exist it would be a interesting trip to go there, although I must say that there are some seriously scary things out there in this world that do require lots of explaining. Dragon skeleton was really cool though.

2009-09-20

FAILURE ANALYSIS REPORT

EVENT:

On Saturday, September 19th, 2009
Multiple confirmed reports of flat and unappetizing beer piled in. Customers reported watery and flat tasting beer, as well as bottles that did not foam or pop when opened.

ANALYSIS:

On acquisition of the available samples, analysis confirmed that due to a manufacturing defect, the majority of the batch #3 was lost due to a sealing leak in the rubber o-ring of the bottle caps, similar to the challenger shuttle disaster.

In depth analysis shows that no step in the process was misaligned; All employees were intoxicated as preferred, and every procedure to the letter was followed. No single person or human error is at fault. However, the materials provided by a separate manufacturing firm were the cause, as the bottle caps provided were not compatible with the bottles, as was stated. This error could have been detected with a simple radius and sealing mechanism test; And this procedure has now been implemented into the brewing process to prevent further issues.

Exhibit #1:

The bottle on the right is correct; The bottle on the left is a defect.



As you can see, the evident leakage of gas has caused a net change in volume. This is directly indicative of a leak in the container. Also, the sediment ring proves that the fluid level has decreased over time. The cap is slightly ajar as well.

Exhibit #2:

The cap on the top with the synthetic white seal is the correct cap; The cap on the bottom is the defect.



Examination of the caps shows the first used caps, the superior, synthetic plastic white sealing ring correctly fits the mouth of the bottle we are using. The inferior, waxy gum cap below does not sufficiently seal the bottle, resulting in predictable cap popping and leaking. Both caps are identical in dimension, weight, size, save for the sealing gasket.

SOLUTION:

Beer brewing process now includes examination of bottle caps to inspect for matching radii and proper sealing rings.



I, Imaginary Z, as the owner of this brewing establishment owe a large and deeply felt public apology. Our customers should never have to face this kind of tragedy, as it not only leaves a bad taste in our mouths, but hurts all involved. You trust us to deliver a solid, consistent and refreshing product, and we have, through sheer accident, failed you. As our company motto stresses quality and consistency of delivered products, we have already corrected this error to prevent any future incidents. If you are a victim of this tragedy, please, visit or write and we will do all we can to make it right to you.

Sincerely,

Imaginary Zephran

2009-08-16

Pics, as stated

One, we have the lovely 'Ryuou' / 'Valgirt' from Dragon Quest Swords (11k poly, 272 bones):



Two, we have the awesome robotic 'Kiryu' / 'Mechagodzilla' from Godzilla: Unleashed (6k poly, 69 bones):



These pic's don't show much except that the importing is pretty near flawless into blender, including weights and other nifty things.

Side note, I'm using the GLSL display option in blender, and have a script that converts I8A8 normal maps into RGB = XYZ normal maps, so that blender can use them in the shaders it has. Also, the light setup is a new one I'm experimenting with, that has two hemispherical lights always 180 degrees apart, but only one is applying specular components. It is similar to a ambient light, but seems to be a little nicer. Once I finish my CIE Lighting model shader, I'll try making that mess happen.

And, of course, both of these models are copyrighted to their respective owners. Go buy the damn game(1)(2) if you want them yourself!

-Z

2009-08-15

Hacking Success; Dragon Quest Swords broken!

Add:

Godzilla: Unleashed
Rampage: Total Destruction
Dragon Quest Swords
Monster Hunter G
Monster Hunter Tri
Super Smash Bros. Brawl
Carnival Games *
Super Mario Galaxy
NiGHTS
ect...

to the list of games I can extract models from.

I wish I knew who to give credit to, but all I needed was this little function here to finally break apart the .fpk / Dragon Quest Swords compression format (I was really close too, ironically)


typedef unsigned int u32;
typedef unsigned short u16;
typedef unsigned char u8;


int endian=1;

u32 BE32(u32 data)
{
if(endian)
return ( (data<<24) | ((data<<8)&0x00ff0000) |
((data>>8)&0x0000ff00) | (data>>24) );
else
return data;
}

int blen;
int fbuf;

/* PRS get bit form lsb to msb, FPK get it form msb to lsb */
int get_bits(int n, char *sbuf, int *sptr)
{
int retv;

retv = 0;
while(n){
retv <<= 1;
if(blen==0){
fbuf = sbuf[*sptr];
//if(*sptr<256)
//{ printf("[%02x] ", fbuf&0xff); fflush(0); }
(*sptr)++;
blen = 8;
}

if(fbuf&0x80)
retv |= 1;

fbuf <<= 1;
blen --;
n --;
}

return retv;
}

int uncomp(char *dbuf, int dlen, char *sbuf, int slen)
{
int sptr;
int dptr;
int i, flag, len, pos;

blen = 0;

sptr = 0;
dptr = 0;
while(sptr < slen){
flag = get_bits(1, sbuf, &sptr);
if(flag==1){
//if(sptr<256)
//{ printf("%02x ", (u8)sbuf[sptr]); fflush(0); }
if(dptr < dlen)
dbuf[dptr++] = sbuf[sptr++];
}else{
flag = get_bits(1, sbuf, &sptr);
if(flag==0){
len = get_bits(2, sbuf, &sptr)+2;
pos = sbuf[sptr++]|0xffffff00;
}else{
pos = (sbuf[sptr++]<<8)|0xffff0000;
pos |= sbuf[sptr++]&0xff;
len = pos&0x07;
pos >>= 3;
if(len==0){
len = (sbuf[sptr++]&0xff)+1;
}else{
len += 2;
}
}
//if(sptr < 256)
//{ printf("< %08x(%08x): %08x %d> \n", dptr, dlen, pos, len); fflush(0); }
pos += dptr;
for(i=0; i< len; i++){
if(dptr < dlen)
dbuf[dptr++] = dbuf[pos++];
}
}
}

return dptr;
}



Thanks to that mess, I could use my own BRRESToOBM and the Pipeworks1.4ToOBM converters to completely extract the models and import them into blender.

Why do this, you ask?

Simple! Since NOT A SINGLE DAMN PERSON here is competent enough to help me, my only method of QA/QOS/QMS/verification is checking my work against commercial products. It's a very useful method as you often get to see techniques for animation, texturing and shading that are well known to industry but not well documented, or just plain hard to find.

Some of the cool things I've learned:

*Use additional bones inside of the arm joints on your characters; This allows you to retwist the arm visually while still keeping the IK chain unbroken. This is a classic character animation technique that I never had seen in practice.

*Use lots of matrices and bleed the weights out as much as possible, trying not to exceed 4 weights per vertex; Don't just use 0.5/0.5 blending factors (Valgirt has 272 bones...)

*If you are applying a bump/normal map to a character, use the I8A8 texture format and simply calculate the z component in the shader; This costs no additional instructions AND guarantees a normalized z component which you would have to do anyways.

*Use well painted textures, and don;t be afraid to use non-contiguous models (fins, talons, tongues, even neck/finger joints do not always have to be connected to the base mesh!

*Make sure you add in additional transform bones to characters, such as a Root Node and X/Y rotation nodes.

*for mesh modeling, targeting 3k verticies isn't really an issue.

*Always sort your meshes by: Material, Matrix Deformation Pool, Index array type.

*Always convert your final mesh pools into triangle strips if you can; Avoid quads and triangles. If you must use triangles, sort them in a indexed triangle list so that each next triangle shares adjacent verticies. Note that on file loading, you can always convert strips back to triangles; but not the other way around.

*Matrix deformation systems allow you to do things you could never do with bone animation systems; Since you just get a 3x4 float matrix per 'bone', you can apply translation, rotation, scale, and shear transformations. Since the hardware is unaffected by the values you put in those matrices (same number of ops) you're allowed to really have fun animating and be guaranteed consistent results anywhere.

*Mesh keyframes are A-OK and should be combined into your matrix mesh; for example facial poses and stuff. Simply apply those before running your mesh through the shader; You can get very awesome character animations this way.

*Try and avoid making your matricies match a 'skeleton' of you character; This often results in hard mechanical animation that looks not fun. It also makes your artists have to work harder, because a 'bone' does not behave like a matrix. Usually, with matrix deformations, you want the matrix to be at the 'ring center' of the mesh data, so that scaling and transforms will behave as you expect. Interestingly, since matrices have no constraints, you can always make this look like the hard mechanical, but you can't do that the other way around.

*Add additional target matricies; It only costs a small amount of CPU and gives your models flexibility for grapple animations, picking up objects, and easier cinematic animations

*I've seen 11,000 vertex models fully shaded on the Wii. No kidding. With 200 + bones. Think about that for a second. Think about how much more powerful your PC is than that.

*Most importantly, animate/design for fun. Don't make things realistic; It's a waste of your time because commercial studios can always do that better than you can. And who wants to play a realistic game anyways?

I'll post pics later, today I have more beer to acquire!

-Z

2009-07-18

ZLB is zlib from Starfox Adventures

As a side note;

It turns out a lot of Nintendo titles use zlib compression streams for their data formats.

Most importantly, the infamous 'ZLB' format within the Gamecube's "Starfox Adventures" is nothing more than a normal zlib stream. Go download the zlib source and compile your own test to prove this.

If you see zlib compressed data, you generally see something like this:

78 9C - Wii games (sometimes)
58 85 - Starfox

Followed by apparently meaningless bytes. If you read how zlib works, you'll learn more about how that compression format really works, and as always, UTSL (Use The Source Luke)

I still have not cracked the Dragon Quest / Monster Hunter compression format. That one will be tackled next, it seems easier now that I have a decompressed block of data to compare & reverse engineer.

Amazing what you can do with a little perseverance and a lot of intelligence, eh?

Next up is trying to get some locals here to help me make XNA fun stuff. Just for kicks, since there aren't many people around here competent enough to want to make games for fun anymore.

No surprise. Some people actually value social time over working, and some people 'have a life' as they might say.

Peace!

-Z

2009-07-04

Technically Competent Flash Game Engine

After playing with flash enough (Flash Professional 8)
I've reached a conclusion about how to build powerful, dynamic flash games.

I've worked with flash off and on for years, C/C++ and OpenGL are much cooler, but it has become difficult to manage my pipeline without additional tools that do not exist; So I am taking a break from that for a bit.

In order to properly make a flash game, you must first understand what a 'video game' is and how it works internally; They are full of interesting technical challenges as well as evil hacks; Because a game tends to be a simulator or emulation of some system, that means we'll never be able to truly make exactly what we want, either due to time or power constraints.

With that in mind, let's build up a 'megaman' example game.

We know from playing the megaman series on the NES that megaman is a little robot dude that can shoot other robots, some of which can move around and shoot back! And, if he enters a boss room, he can shoot a special enemy that can give him additional weapons!

Not much else too the game, really! Let's generalize it.

What kinds of things are there in the game?
-Sprites (2D Pictures)
-Sounds (Sound effects)
-Music (Longer strings of sounds! .nsf or some other mod format)

Well, that's kind of an aesthetic look. The actual game however, isn't quite as simple, as there are a variety of object types, like each type of enemy, each type of bullet, and so on.

When we look at a game from the programmers perspective, we can group all the things that work that same, and build a hierarchy:

Object
-Sprite
-Moving Object
--Bullet
--Controlled Moving Object
---Enemies
---Megaman

So, for each level down we go, we have to add more special code; There still is no magical way to code each type, that will ultimately have to be done. However, we can reduce the amount of work signifigantly by providing generic utilities for moving and updating those objects;

For example, we can have "MoveAsPlatformingCharacter" "MoveAsFlyingThing" "MoveAsBullet".

And, the ironic thing, is the game is still just moving pictures that can add and remove pictures and sometimes play sounds. There isn't anything more to it than that.


So, stepping back a bit, let's look at what flash can do for us:

-Automatic Heirarchy
-Display sprites, images, movies...
-AND can move, rotate and scale them!
-AND can colorize, shade, ect...
-AND can dynamically draw shapes!
-Automatic Sound playing
-Streaming music palying
-Input handling

So flash can do everything we need! But, flash is not assembly code, it is a SCRIPT LANGUAGE. That means that you cannot apply the same logic you use in C to flash; Script languages are not C, and C is not a script language and vice versa.

So in flash terms, we will have 1 movie clip called 'game' that has everything we need in it, as well as having ALL the functions we will use in it, so that you can do this:

game.moveObject( obj, 4, 0 ); //Move object obj right by 4 units

Inside of the game movie clip, we must have all the clips we want to duplicate in real time. Usually this is accomplised by:

game.dup_character;
game.dup_bullet;
ect...

Where, inside each of those dup_character, you have a lot of named frames for that specific character type, like "Heatman", "Iceman", "Megaman", and in each of those frames, you put down the instance of the clip you want to animate; you do not do the animations in the duplicate clip, you make a seperate layer;
This way, you can name each clip inside of the duplicate clip the SAME THING, ergo: "mc", so that the game can reference the mc identically for each instance, AND separate scaling and other properties from it.

[MovieClip: dup_robot]
[FrameName : "Megaman"]
mc [Instance of "Megaman" movie clip, which has all his named animations, like "run", "jump", ect...]
[FrameName : "Heatman"]
mc [Instance of "Heatman" movie clip, which has all HIS animations ]

so your 'game' clip now has this:

[game : Game clip]
dup_robot [Instance of "dup_robot" movie clip, which has all the possible robot types each in a specially named frame]
dup_bullet [Instance of "dup_bullet" movie clip, which has all possible bullet types each in a named frame]
ect...

Using this method, you can simply duplicate a dup_clip, then set it's frame, then once you do that, you can set the mc inside of it's frame, thus instantly allowing your game to be very flexible to add extra things later!

So this is all fine and dandy' Now in flash you can duplicate any clip that graphically represents what your game is, but, what about the actual game?

Here's where it get's difficult; If you trust flash's 1 collision function (hitTest) then you might know that it DOES NOT WORK on and point test that is NOT on the stage (any non-rendered pixel CANNOT be hit-tested against. SO DONT USE IT!)

That means yes, you have to make up your own collision scheme, and make up your own collision math, and your own physics system for motion.

Basically, that means that every object should have a .x, .y, .vx, .vy in it, so you can perform basic rectilinear motion. As for updating your objects, so long as you make a working rectilinear motion function, you can add any complex types of motion you want later.

This will be covered later, but the easiest solution is to add another dup_clip that creates boxes and ramps, which are very basic and mathematically simple collision primitives that you CAN make a game out of quickly.


But all this high level talk isn't much use; Because when you get started, you'll find you need a couple of basic tools:

Something to store this data,
A Map (dict for those python kidz)
A SpaceHashing/Broadphase test

Map is actually simple in flash,

var mymap = new Object();
mymap[ "any key as a string" ] = data;

So you can abuse flash's quick Log2(n) internal string search for object properties as a map. It's as fast as it get's folks.

A Spacehash is up to you, I prefer using a single axis sort and doing a map/array of bins, which have maps of catergories, each which stores an object UID

Yes, every object you make should have a non-repeating Unique ID. Don;t rely on the movieclip as one, you never know when depth levels can change or clips for that matter. Use a Number and just increment it, or make a map and reuse unused keys.

Blargh; What a mess. Too much information to disgorge for ya'll.

I'll post the flash engine later. Then you can just %#@*(& use it!

Happy fourth!

-Z

2009-06-21

Pokemon Battle Revolution - h4x

Interesting theoretical question;

Let's say you make a video game with monsters such as Lizardon (Charizard for some);

And you want it to have different textures so you can make different colored versions.

The logical thing to do is to add the textures as references, or make a named texture set so your model can just quickly request a texture set switch, right?

Apparently, someone at nintendo didn't get the memo, and instead, they JUST MAKE AN ENTIRE NEW FILE which has the additional textures in it, ignoring the fact that the entire model set is identical and only the textures change...

For example,

Mr. Lizardon is ~ 800 kB, compressed.

When you decompress him, you get:

lizardon_0 ~ 1024 kB
lizardon_1 ~ 1024kB

So, the funny part, is the textures take up maybe 200 kB of each file.
If they would have just added the textures in, it would have saved nearly 800 kB, and who knows what that translates to in the compressed format!

Weird enough. Also, it explains why some of the colorings I had were dead wrong (is it?)



Oh well. Once I figure out where it tells me how many vertex arrays / vertex objects there are, I'll have it nearly 100% exported.

Peace!

-Z

2009-06-20

Pokemon Battle Revolution - h4x

The first thing you probably said was "Pokemon!?? @#$%%(&!?" with more expletives.

On a side note; It was useful to decode the LZSS varient used in these games; It offers a serial form of compression that is very good at packed redundant data, and is byte driven instead of bitwise like a huffman. It seems to get pretty decent compression ratios for sparse or repetitive data; and is general & lossless. Also, learning more block compression schemes for pixel data is useful, PVRTC is the only one I care about at the moment, but STC3 and some others are handy for my own projects. Do they have a normal map compression scheme yet? hm.

On the actual note; I'm not sure if finding out how pokemon are made is useful; But it does show me just how crappy textures can be if you use shaders properly.

And, why would they use vertex keyframe animation? Makes it really really hard to integrate into any other system; Might explain the lack of Digimon/Monster Rancher type games. Oh well. Only theories.

Here's some random pokemon in Blender; No credence given since I never played the games:



-Z

2009-06-13

You're fucking right

So I have yet another bad day out of my 27,375 available.

Solution Time.

1. Create my own 3D animation tool that does what I need it to;

2. Open it to the community via Sourceforge;

3. Integrate IGTL::Sys into the mix to improve both components;

4. Create 1 x demo project to showcase how it works in a pipeline.

I've named the project; Once I finish the design specifications it's on to coding it.

Planned:

*Support for full 3D Joint/Matrix based animation (Hardware level matrix joints, with bone display option for seamless transitions from your old tools)

*Support for the newly popular UVS animation (Using bones as 2D billboards that have x,y scale and can change uv coordinates per keyframe; Think Odin Sphere)

*Perfect Data Editor so that all data can be viewed/changed irrespective of present 3D view/mode, as well as locking and visible flags for all pieces of data.

*Keyframe based animation on a discrete timeline; So be sure to start with your base FPS set correctly (default is 50)

*Logical flow to data and animation; No 'global timeline' exists. Everything is animated from 'Strips', and 'Sequences' can be made from and combinations of strips

*Mode driven editing; Object mode for scene objects, Mesh Keyframe mode for mesh objects; Pose keyframe mode for Joint/UVS objects.

*Level Of Difficulty integration; Default system is super simple; Advanced users can tweak and expand editors as needed to suit their work mentality

*Entirely abstracted input with multitouch support; Any Human Input readable by SDL can be used and assigned to hotkeys/event keys. This also means you can record some macros within the program. (Automation tools)


Some obvious problems:

-Exporting will be limited initially to a text format for inter-compatibility; So long as the text format specification is rigid (like OGRE xml) then anyone can easily write a converter from text -> custom.

-Speed and User friendliness; If you do not have OpenGL 2.0 or a newer graphics card, the program will initially deny you the ability to use it. This will be fixed later because it is not a priority to write my own TnL for OpenGL 1.1 users. I have done so before, but this is the lowest priority item.

-Operating Systems; Windows and Mac and Linux don't seem to have multitouch support in the SDL I am using. Too bad; I'll have to store special mouse states for 'virtual mice' aka joysticks.

-Networking; I want this program to allow collaborative editing; This is always difficult to do and not a priority item because it is outside the scope of the first version, plus this would be mostly beneficial for scene editing and individual animations; Think cooperative moviemaking

-Rendering; This program is NOT a rendering tool; It can export frames, but onlt as good as your graphics card can make them. I do not want to write a rendering pipeline; But I should include exporters so you can dump a animation to a real rendering program like Blender. However, this is also a low priority item due to it being outside of the scope.

-Complexity; all good tools have reasons for complexity; Generally it is lazy programmers, but that's because some of the basic problems are very difficult, and they have timelines to meet so they do 'the dumb yet it works' solution. I am doing this for no profit, so there will be slowdowns in the development of this tool.

-3D Mesh Modeling; I do not want to make a mesh modeler; That is blender's job, not this tool. I want this tool to focus on making game animations with an existing mesh, as well as weighting the verticies of the mesh in the program. This means I will need some mesh tools; and that means the first thing people will demand is a mesh editor/generator. This is a low priority and not the scope of the program, though I may add some cool tools for it in the future; especially because re-meshing is common in real industry; which includes re-uv mapping and adding/removing some verticies. This will have to be supported and is a medium priority item.


I plan to have it work a lot like blender. I hope if I build it, indy developers and hobbyist animators can use it for their purposes and avoid the headaches with classical paid program nightmares.

This should take me at least 6 months to get a beta out.

-Z

2009-06-10

Extremely Depressed

As stated, I am very sad.




More than 10 years of programming, multiple jobs, and even an engineering degree later, I'm still not happy.

Here's why:

Blender, being the free opensource 3D wondertool had intrigued me from when I first found it. However, after years of playing, making animations, and games using this tool, now that I entered the realm of 'real' game development, blender is severely lacking in multiple areas.

1. Armatures

The concept of a armature is invalid; The 3D graphics hardware you have and have had since 1970's has always been of the 'projection matrix' * 'modelview matrix' => output raster position. Now, modern 3D hardware has the ability to be programmed, so, people like me can code in fully articulated characters by adding weights per vertex and writing a simple vertex shader that multiplies by each joints matrix.
Blender does not conform to this universal standard; IT instead tries to 'make it easy' by giving you a 'bone', which, here's the serious problem: It has a length. Matrices deform from their center, not an arbitrary point. This makes conversion to my game and from my game to blender impossible, thus, blender cannot be used for the animation pipeline. Any attempt to 'hack' blender into making this work is a waste of time; True, you can constrain your game a lot, but if you had 1/100th the experience I do, you would know better. Now for another point; Even with armatures, blenders animation system is designed for movies; That is, everything works on a global timeline via global IPO keys. No game works like this, so combining run + walk animations becomes very difficult, as well as keeping track of current animation track data. They have botched and fluffed over this for years; No positive results yet.
In conclusion, thanks to a broken bone system and incompatible animation keying system, I now no longer have a animation tool my artists can use for our pipeline.

2. Space conversions

Blender doesn't use math centric +x forward, +y left, +z up space consistently. This causes nothing but headaches for everyone. There is no justification for having inconsistent coordinate systems, pick a coordinate system and make your entire program be consistent.

3. Pipeline

When I make a model in blender, I use my character sketches and some quick concept coloring. Blender makes mesh modeling quick, which is nice. However, when I finish with my model, I want to take the data out, and put it into my game. There are many options for this, but, I usually have to write my own converter. Given, every single update of blender, guess what? My converter breaks somehow thanks to a undocumented python function or change in the way things work. Usually the breaks are not too large, but this is a lot of my time wasted for something that the program should do automatically; For instance, 'dump ascii' should export a large, concisely documented ascii file of all the data for the current selection, including it's linked data and so forth. If they wrote a game engine in blender, why can;t we dump that data out? And why do I keep having to make more converters to spit out a text file?

4. Data Model

Blender uses a older C-Data model. This is a good one to use, however, I would like to have more data model tools; For instance, if everything is reference counted and deleted on zero counts fine; But let me control that and show it to me in the OOPS or a special 'data tree' viewer. As a developer, I need control for that data to better improve the exporting I have to write for this tool. Also, sometimes blender files get junked up with bad chunks from older files. And, more importantly, where is the .blend to ascii converter? That would be very nice to have.

5. Next Gen Content

Blender currently is pathetic when it comes to this; Let's say I want to make a MGS4 snake. No problem you say, and model out a nice 3300 poly Pliskin and then build an armature for him. Now, you can bend and animate him with some ease, though, lookie here, his shoulder bends funny! Well, after about an hour of tweaking the armature, you got it to look better, but not commercial quality. Now you have to generate a mesh keyframe and link it to a python controller that listens to the armature. Okay, fine. But, how do you export that data out of the system? And how do you ever preview your animations if keyframes are global application? Hm, looks like you have a severe problem editing keyframes and armature actions. OH NO, you added visemes so snake could talk; Looks like there's no way to make animations except by manually entering times on the timeline; oh, and look, while he's talking the python controlled armature actuator is fuzzing the keyframes... Looks like you just wasted 8 hours fighting a system that wouldn't work anyways.
Enough bitching about that example; Point is, if you have a animation system, but 1 special component can have 'local' timelines (armature 'actions'), why can't mesh keyframes and other animation systems have 'time strips' that you can make, so that your main animation system can paste strips together? Oh what's that? NLA? only works with armature actions, sorry. Unless you're making a movie with no dynamic content, you're SOL here. And try writing an exporter for that. At least they finally added GLSL to the damn system.



I'm so depressed. What do I do, write my own tool like FrameGL3 (already solved all these problems myself btw; SDS, IK, anims, ect...) or do I just give up? This is a lot of work for anyone to undertake; Only because of the gruntwork required. More importantly, there has to be someone else who has this problem, but where is there solution?


Also, being unable to crack 'Dragon Quest Swords' funky LZSS type compression really has me down. But not down like Valgirt Nedlog has me down; fucker's hard!


Maybe I should give it all up for a while, like, a year or something...


I'm in the wrong fucking state/country/planet...


-Z


As a side note; I've hacked the graphics out of Primal Rage 2; Killer Instinct; Wario World; Super Smash Bros; Turok; and many other games just to learn how they built their data, as my ONLY FORM OF VALIDATION that what I have been doing is correct.

2009-04-28

Dream; A Better Japan

I went to japan with Brien an John.

But this wasn't old or new japan, this was Eden japan.

After we got out of our plane, and walked into the airport terminal, it was obvious that Japan was no longer like it's former self; they had mastered use of space and eliminated building ridiculous amounts of structures for ridiculous amounts of people. All of the advertising nonsense had gone away, the airport was very small, because it only needed to have the airstrip large.
So we take a walk instead of taking a taxi or bus, and walk right into the middle of this city, that, unlike current japan, isn't full of skyscrapers and people congestion, but rather a very clear air to the place, no trash anywhere, the density of the population was reduced heavily, there were trees, parks, and lots of green things all over the place.

Interestingly, we get to walk by this water park thing on the corner, near the ocean. This part of the dream more or less catered to my interests, so skip if you want. There was this large quarter circle wave pool, at least 200 some feet radius, and in the middle it had this pretty awesome water slide, which was naturally decorated like any typical asian dragon should be. The only interesting mechanical aspect was the slide was tethered and stable, so it could actually move around, which changed the slide as you were sliding, kinda a cool design, made it pretty intimidating, though the graphics were cute and funny, so it wasn't too terrifying. The way it moved was unusually organic though, and like all waterslides of this type, you start at the tail and come out the mouth. I asked a local about this craziness, and they pointed to a holo-prompter, which played a little holographic video detailing the history (faked) of the slide itself. Apparently, back a long time ago, there was some great conflict over this portion of the sea, and two warring families were causing so much bloodshed, that it angered one of the great dragons enough to come and destroy the commanding officers (this is accompanied by a nifty animation where the slide morphs into it's real form and devours all the warriors at that point in time, yay.) before settling down into the form you see now. Knowing that transformation ideals weren't uncommon in japan, I dismissed this mess and moved on, so we walked toward the city again.

On first glance, we get to see that most of the buildings aren't much taller than 14 or so floors, and appear to be made of bricks and glass, adhering to earthen tones and less harsh colors. There were hardly any steel buildings to be found, and every mile there was at least 2 acres devoted to a green park, where most of the people were milling about, talking, or, as the case was, riding the little carnival rides and buying stuff from street vendors. It looked in spirit a lot like the first part of chrono trigger, really. In either case, we were trying to find where Elena was, and we wandered onto the highschool campus, which had some very ominous prison like brick buildings, with darkened glass. School was always in session, and their highschool was not just that, but also a university, implying that education could be learned on a college level if you so desired. The campus had a few buildings too, and spanned a good chunk of space, with plenty of park inbetween it, much like OU's mall areas, but much greener and more well maintained, which is easier for a place that doesn't have the kind of weather we do.
So after talking about the high school, we began to walk toward main street and all the commotion, nothing much fantastic happening yet, there was a giant ferris wheel in the middle of the town and some sort of festival going on, with generic fair foods and booths, people were in general having a great time; so we got some sake and joined up. Although, the japanese people were different this time, they would make eye contact and greet, though I believe this is a function of alcohol rather than culture.
Eventually, after walking around this city for a bit, we found the building we were looking for, and the camera is forced to undergo a fade till we arrive at scott's new lab, which is larger than his current one but still just as messy. We talk to him for a while, and hang out talking about some disease that had occurred, as if there had already been a life cleansing tragedy that occurred naturally, and he remembered he had a time capsule somewhere in the ceiling (raised ceiling) so that the government wouldn't find and destroy it; Apparently the japanese government destroyed their history in order to maintain order or something stupid like that. So we much around trying to find his box, a maintenance guy comes over and asks what we're trying to do, scott makes up an unbelievable lie, the guy doesn't care, and tells us he'll do what he can. About this time the alarm goes off, so that ended that.

Nothing fantastic happened in this dream, it was pretty tame, not much more than a elated feeling of walking around this happier, more dense world. I think what really struck me was the cleanliness, things weren't like in america where we sacrifice our planet for speed and profit, it was emphasized with nature, temporary materials were all rice paper variants, there was no trash at all anywhere, all of the greenery was well maintained and practical rather than just looking pretty, sporting herbs, air cleaners, fresh smelling flowers and fruit trees. All of this would have failed if the people have been fucking it up, as they usually do, but that didn't happen here. Something had these people trained, or no longer living in fear. I'd like to believe it was that waterslide.