Wednesday, July 29, 2015

Broken Mug Engine - Game inside a game

A little demonstration of the "activity" stuff I wrote about in the last post. It's not Super Turbo Turkey Puncher 3, but close enough. Do note that at 0:25 I'm using a GUI several levels deep, and the screens are displayed on dynamic objects that move, and everything is zoomed in.




Tuesday, July 7, 2015

Activities

First update after two months... I am rewriting the core of my engine. The once all mighty engine class is just a resource manager now and all user interaction is now handled trough "activities" (I didn't know how to name it, and it is inspired by Android Activity). Core creates the app window and sends input to active activity. Game is just an object now, it extends the activity class with game related stuff. Activities can render directly to screen or on a local FBO.

What I can do now, for example, is create a new game object inside the editor and display its FBO in a window for easy map testing (you can see I can fire the gun in left window). This is very WIP, still need to figure out window focus, pausing, closing...


Thursday, June 4, 2015

Random thoughts #4

I lost a big part of my motivation months ago and I thought the AI development will spark a new interest in me for coding, because that is one field I never really explored...but it hasn't. Then, few days before I posted about ambient occlusion, my new PC started crashing randomly. That didn't help at all. I thought maybe drivers got messed up or something, so I reinstalled Windows (I was planing to do that either way), but it didn't help. I haven't bothered installing Visual Studio again...

Long story short, don't expect new updates any time soon.

Friday, May 8, 2015

Ambient occlusion in a 2D scene


Thanks to a tip from this guy I got an idea how to do some sort of fake ambient occlusion in a 2D scene. I improvised in Quake 2D from 2012 by manually placing black shadowy textures around background objects, trying to make the scene look less flat, but that was very time consuming.

Gaussian blur with a large enough convolution kernel/matrix makes the object's colors "bleed" into its surroundings, basically scaling it while blurring. So, all you need is that blurry scaled object rendered in black before you render the actual object and... BOOM !


No ambient occlusion

Manually placed textures in Quake 2D (2012)

Ambient occlusion using FBOs and a blur shader


Shader


I found some good tutorials to make Gaussian blur in GLSL (here and here), but strict Gaussian weight values are not necessary. I am using a two pass blur, meaning first I blur in horizontal then in vertical direction, the reason which is nicely explained in above tutorials:



Here is the GLSL shader code I used:

#version 120
uniform sampler2D img;//texture 1
varying vec2 texcoord;//vertex coordinates
uniform float sw, sh, z;//screen width, height, zoom

uniform float hpass, vpass;//set in application to do vertical or horizontal pass(0 or 1)

//weights
float w[33] = {0.040,0.039,0.038,0.037,0.036,0.035,0.034,0.033,0.032,0.031,0.03,    0.029,0.028,0.027,0.026,0.025,0.024,0.023,0.022,0.021,0.020,0.019,0.018,0.017,0.016,

0.015,0.014,0.013,0.012,0.011,0.01,0.009,0.008};

void main()
{
    vec4 sum = vec4(0.0);
    //pixel size
    float px = 1.0/(sw*z);
    float py = 1.0/(sh*z);

   
    sum += texture2D(img, vec2(texcoord.x, texcoord.y)) * w[0];   
    for(int i=1;i<33;i++)
    {

        //add values right/down from current position
        sum += texture2D(img, vec2(texcoord.x + i*h
pass*px , texcoord.y + i*vpass*py)) * w[i];
        //add values left/up from current position
        sum += texture2D(img, vec2(texcoord.x - i*h
pass*px , texcoord.y - i*vpass*py)) * w[i];           
    }   
    gl_FragColor = sum;
}

 
Rendering steps


1.) First render whatever you have in the background.

2.) Then you need an offscreen framebuffer(FBO1) that supports alpha channel and that is the same size as your screen*. Clear it to (0,0,0,0) so that it is fully transparent and render all the objects/textures(a), that will have the outline around them, in black(b). The FBO needs to be transparent so that when you render the final result over your scene, you can see the stuff you rendered before.

a)                                                  b)
 c)                                                  d)

3.) Render FBO1 to another transparent frame buffer(FBO2) like the first one using the vertical(or horizontal) blur shader.
4.) Then take FBO2 and render it over your final scene using the horizontal(or vertical) blur shader(c).
(If you are using a single pass blur you could render it directly in 3 and skip this step.)
5.) Then render all the objects you rendered to FBO1 in step 2 to your final scene as they are. Those will cover up unnecessary middle parts so you get the outline effect aka ambient occlusion(d).


BOOM !


*You could speed up this technique by using a frame buffer that is smaller then your scene and using  a smaller kernel. Then you need to render the final result scaled up. More info in the first linked tutorial (Working in lower resolution).

Sunday, April 26, 2015

Basic path smoothing

I added some basic path smoothing based on the visibility between nodes. The white line shows the path calculated by A* algorithm. To generate the "smooth" orange path I go trough the original path and check if nodes can see some other nodes further along the way, if so I make a direct connection with it, skipping the nodes between them.





The other thing you can see is adding temporary nodes to the mesh (yellow start, magenta end). I check what triangle/polygon the cursor is colliding with (pink triangle) and then make a connection with the nodes in the vertices.

***

I've read a tutorial where the guy checks visibility between nodes to make the connections and build the tree, then this method of smoothing isn't necessary. But in a map with so many vertices the number of connections would be insane, and would probably slow down the A* algorithm.

I should do some testing to see which is faster:
- connections based on triangulation + path smoothing that uses B2D raycasting,
- connections based on visibility between nodes,
but nah...

Thursday, April 23, 2015

A* pathfinding and navigation mesh

Working on navigation mesh for AI, this is generated automatically, by selecting an area with a mouse. I'm using Clipper library for this. You can notice the offset from the inner polygons :




Didn't know how to connect vertices in the navigation mesh, so I triangulated it with Poly2Tri and used triangles to form connections. I will have to ditch Poly2Tri for some library that generates polygons instead, and do some "path smoothing"; starting from the yellow node, the node 10 is visible from 5 and should be directly connected in the final path.



In a platformer game this could be used for flying enemies. Triangles/polygons will be used to know in which area the entity and its target is located, so I can quickly get the nodes nearby, connect with them with a temporary node and calculate the final path.

Monday, April 13, 2015

SDL_net networking and multiplayer test

This video shows a "Soldat meets Quake 2 arena" multiplayer prototype I basically made already in January. It took some time to get motivated to fix bugs, add some features and make it look decent.




The first part of the video shows networking based on SDL_net tutorial by thecplusplusguy. It uses TCP to send data between server and clients. The data is just plain text. I'm not saying all this works and is how it should be done, this is just to show what I've been working on, to do some testing and get some feedback.

As for other players in the video, those are not people playing with me. They are just "bots" who read my stored input commands and send them to server to move each other.

Only thing that I try to keep in sync is the player. The client sends input commands to the server, server updates the game world and players, and sends the player states and the input commands back to to the clients.
For example, player fires a bullet on the client after he gets his own state and commands back from the server. The bullet on the client and server have nothing to do with each other, they exist in their own Box2D world, but only the collision with the players on the server counts:
- It can happen that the bullet goes trough the player on the client if the server kills him before the local collision is detected.
- Also ragdolls are not in sync, because they don't get velocity and rotation values from server.
- Explosion force and gibbing are disabled on multiplayer.


The second half of the video(1:30) shows an offline bot match. As said above there is no real AI, just stored commands that they read. It doesn't really work, but is good enough for testing and to have some fun.


HELP WANTED !
I only managed to make multiplayer work using local IP of computers connected to my wireless router. When I host a server and try to connect using its public IP address, it fails. I did port forwarding on my router, but it didn't help. I don't know if the problem is with my code, or router and firewall settings. I newer hosted a multiplayer server, so it would be great if someone more experienced would try to test it out.
I downloaded a game called Teeworld to test their server. Sometimes I can connect, sometimes I don't, so I assume it's because of my router or firewall. 

 Either way, any feedback is welcome. Even letting me know if it started successfully(or not) would be something.

MD5: A2DFC602CA5C1E3A46D1D9DD85B06ED3 
Missing READ ME

SDL_net tutorials by thecplusplusguy:
www.youtube.com/watch?v=LNSqqxIKX_k
www.youtube.com/watch?v=iJfC4-yNnzY

Original map design by HardcoreMazu:
www.youtube.com/watch?v=cNkiVTTVtGI 


Disclaimer: I don't own any of the textures and sounds used to make this demo. I advise you not to download if you don't own a legal copy of Quake 2 by id Software.

Tuesday, March 24, 2015

Random thoughts #3

It only took 7 months for someone to download one of the public builds and report back... that it doesn't work. Unfortunately the old game log didn't help and needs more work.

Either way, thanks to anonymous.