Pages

Saturday, December 10, 2011

So I want make an MMORPG, Where do I start from? PART 4

Messaging and optimizations:

<Messaging:>

Networking is the core of an mmorpg, and just in the top of the network we have the messaging system. What we need is to create a way to communicate between server and clients.

Clients will send commands to the server for example: move forward, turn right, atack!... In the server we could have comands to send the map, the clients data like player / npc position,etc...

Most of the people (should) use serialization to send data, for example an item could be packed in an object / serialize it and send over the net, in the destination it would be deserialized and here we have our object/item again, but I have used another way to transfer messages that is hard to code but easier to understand: Plain-text messages.

Probably now you are wondering about how does it works, suppose we want our client to send to the server we are moving forward, then we will just send a command telling the server we have pressed "forward", suppose we decide the text command is going to be "/acce", when the server receives a string "/acce" from our client it will understand the client is moving forward so it will move the client forward in the map and return the new updated position to the client; The server will send "/ping" to the clients every x seconds ,when the clients receive "/ping" it will return "/pong" to measure delay in the communication between server/clients.

What are the advantages when using this method? basically it simplifies debugging , it's easier to understand an incoming packet when you can actually see the command and not a binary-format hex value, basically it is good for didactic purposes.

The disadvantages? performance and scalability , "/acce" uses 5 bytes to send "forward", too much for a simple commands in the other side for every new command you have to modify both client and server, that can be overwhelming!

I resume here all the commands I used for the demo:

Client side:
  • /nick > Set players nickname
  • /imag > Set players image
  • /acce  > Move forward
  • /dece > Move backward
  • /righ > Turn right
  • /left > Turn left
  • /idle > Stay idle
  • /pong > Answer a /ping request
  • /quit > Exit server

Server side:
  • /SUID > Send Unique identifier to the player
  • /upda > Send non-player updates (X,Y,Nicknames...)
  • /updb > Send player updates (X,Y...)
  • /ping > Send a /ping request to calculate client latency
  • /kill > Sent when a player logoffs
So we have our server running, in our client we create a player and then connect to the server, then the client will wait until our server sends "/SUID" with the UID for our client, the UID wont change until we logoff, after receiving the UID our client will send our nick and image, that is how our "enemies" will see us, then we are ready to explore.

We will start moving around, when we move we will be sending "/acce", "/dece", "/righ" and "/left" to the server that will update our position in the map, if we don't move a "/idle" message will be sent, when the server updates our position it will mark if the client has changed state so it will send the command "/upda" with our updated x and y to the clients in a range (500px), so server wont send updates to clients that can't see our moves, that will limit too network traffic.

When a clients exits the game it sends a "/quit" to the server, server will clean the players data and then it will send a "/kill" command to the clients so they will clean the exiting client...

<9 messages for the client + 5 messages for the server = total 14 diferent messages! , Probably the simplest messaging system you will have ever seen>


<Optimizations:>

After I made the server I saw two simple ways to improve performance: first one in the client second one in the server:
  1. In the client I was sending 25 messages/ second to the server: I was sending data no mather if it was moving or if it was idle, but I thought that instead sending messages all the time I could only send data when a change was detected, for example: the client is idle, so the first time, it will send "/idle", but if it keeps standing still it wont keep sending "/idle", server will save the command until a new one arrives, so after a while I start to move forward, I send a "/acce" to the server first time, but again if I keep on moving forward it wont send again "/acce".. that divided outgoing messages from 25 to 2 or 3 messages when moving and 0! standing still.
  2. In the server I checked the messages and found that "/upda" >> (client updates) was about 99% of the outgoing traffic, that generated a huge problem when a client was in a crowded area, suppose there are 50 clients near, all them are moving so every client is generating 50 updates / frame, with a frame rate of 20 /s that was 50 * 50 * 20 = 50.000 messages in a second!!! that was making the server collapse, so I had an idea, why not nest packets? when a "/upda" is generated I made the server to don't send that message instantly , instead of that it "packed"  into a bigger message, when more "/upda" messages arraived they were packed up to 10 updates in a bigger one, so in the same "crowded"  are messages sent will be reduced to 5.000, that was much more reasonable.
 With that pair of improvements server was able to handle 1000 clients at the same time with almost no delays , traffic had spikes of 18.000 incoming messages and 200.000 messages sent in a second, but then I reached blocking socket's limits...


<Blocking versus non blocking sockets in the next post>


Monday, November 28, 2011

So I want make an MMORPG, Where do I start from? PART 3

<It had been a long time since I made my last post , part of the problem was because I've been on a trip to Paris (A city everybody should visit at least once in their life), another part of the problem is my fight with non - blocking sockets, but now i'm back and I feel refreshed , with energy to continue with the project.>

Today I'm going to speak about a few things: the server structure ,about messaging  and finally about blocking sockets vs non blocking sockets:

Server Structure:

I plan to make my server architecture based in something like that:

Clients (a.k.a. players) will connect to a login/ authentication server , when validated they will connect to the proxy server, proxy will redirect players to the less loaded server, (balancing server load), server instances will be deployed across the servers on demand ( if a server is more powerful it could handle more instances), all server instances + login server + proxy srv will access the SQL server to write /read all persistent data to be stored, such as:
  • Usernames / passwords for the login server
  • Maps , players and objects for the server instances
  • Number of instances, server instance sockets and health status of the instances (load and failures) for the proxy server.
That is a draft of the design I plan to do, at the moment I'm just working to make a server instance + sql server working, the remaining features will be done later (LOGIN / PROXY).

<Messaging in the next post>

Tuesday, November 22, 2011

So I want make an MMORPG, Where do I start from? PART 2

Welcome back  to the MMORPG series, part 2!


<Incoming connections....>

After expending one year to learn c++ and SDL I felt ready for the next step: Networking.

I did a chat server just to learn how SDL_net works, It is very interesting and I recommend to try to code one to everybody who dares to create an RPG/MMORPG server because it is basically the same with lower processing needs..

In a chat server (basically ) what happens is:
  1. Clients connect to the server
  2. They Login with user name / password
  3. Every time they type something and press <ENTER> message is sent to all the other connected clients.
(I'm not including here channels and other things... it is just for demonstration purposes only)

If you want you can Download the sources for the server and client and test it, (Unfortunately it only works in Linux because if you run it under windows, it will redirect all the output to a file, so basically is useless..).

But for the MMORPG server I had to analyze it before starting....

What happens (basically )in a MMORPG server is:

(Client side:)
  1. Clients connect to the server
  2. They Login with user name / password (Or they can create a new user...)
  3. Wait for the server to send UID (See below), and world data
  4. Transmit actions to the server (update position, use skills, pic objects, attack, etc)
  5. Update world state from data received from the server.
  6. Goto point 4...
 (Server side:)
  1. Allocate resources to accept and process data from incoming clients  (That includes queues and threads to process data)
  2. For every client that logs into the server, assign an Unique identifier that is not going to change until client disconnects, the UID is going to be the identifier for all the process in the server (and the client too), the client will receive too the basic world data to start playing (like map data, players and enemies...)
  3. Server processes incoming data from connected clients (that includes moving around / and all the skills the player have), for example a player moves forward, server receives a message from client(x) that wants to move forward, so it's going to increase client(x)->Speed
  4. Update world state , here it comes were timing is important, the amount of times a world update is applied will change the speed of the game for ALL PLAYERS, for example, players wont send position changes to the server, but  move forward, backward, turn right/left commands, what happens when a world update is executed is that clients will move according to their speed and direction and update X/Y position, so no matter if a client tries to hack the client to run at 100 FPS and not the 25FPS set as default, it wont run faster...
  5. Make a list of the players that have changed state (position, skills used)..
  6. Send updated data from the clients with changed state to all the clients connected and in a X range...
  7. Go to point 3....
I know it is a very raw way to describe what the server does, and you may be missing many features such as maps, skills, enemies / NPCS, AI, etc... but my aim is to make it a simple yet stable network server, then I will add the persistence to do world with  a database (Mysql).

To describe how my server works I'm going to explain how it evolved so it's easier to understand why I changed things...

So let's start to speak with the 3 versions / milestones my server has reached:

<Version Number 0.1:>

Classes:
  • cSockServer: Stores global data , a vector to store all the clients connected, server socket, etc...
  • cSockClient:Stores data for every client such as socket to communicate
Threads:
  • 1x Master thread: Master thread listen for the clients and assigns a new socket to everyone.
  • 1xProcessor thread:It processes the data into the input queues and updates wold data
  • 1xUpdater thread: Insert updated data to the output queues
  • 1xListener Thread/Client:listen for incoming data and inserts it into the Input queue.
  • 1xSender thread/Client:Sends data from the output queue to the client.
Queues / vectors:
  • Clients vector:Here I store clients data (sockets, UIDs, etc)
  • Input queue:Every client has one, used to store incoming data
  • Output Queue:Every client has one, used to store outgoing data
Good things of the design:

  • Very simple.
  • Functional.

Bad Things of the design:

  • Very bad performance, when there was more than 3 clients connected you started to feel it lagging even working with the loop-back interface...
  • There is no time control, so the server will have to be confident in the clients <Horrid mistake>
  • Wasted data: Two threads per client, two queues per client.. too much
What I learned from this version:
Threads are a must when speaking of a socket server, so in this very first version what I saw is I needed to use them in a more efficient way, I was using many threads to just send and receive data to the client but only three to process data.. other big mistake was to use so many queues in the clients, it was a pain in the a** to check them and probably not efficient at all.., with all this things in my head I decided to make an updated version:


<Version Number 0.1.7:>


Classes:

  • cSockServer: Stores global data , a vector to store all the clients connected, server socket, etc...
  • cSockClient:Stores data for every client such as socket to communicate
Threads:
  • 1x Master thread: Master thread listen for the clients and assigns a new socket to everyone.
  • 2xProcessor thread:It processes the data into the input queue and updates wold data
  • 1xUpdater Thread, inserts into output queue the data to send
  • XxSender threads: Send data from the output queue
  • 1xListener Thread/Client:listen for incoming data and inserts it into the Input queue.
Queues / vectors:
  • Clients vector:Here I store clients data (sockets, UIDs, etc)
  • Input queue:One in the server, used to store incoming data
  • Output Queue:One in the server, used to store outgoing data
Good things of the design:

  • Centralizing queues make it to waste less data.
  • Having more threads to process data makes it to be able to handle more clients (watch the screen-shot in the top of the post), 101 clients connected...
  • Timing centralized in the server, more secure now

Bad Things of the design:

  • Still bad performance,after adding 20 clients it started to degrade performance no matter how many threads you added to the server
What I learned from this version:
Threads collide, if you use semaphores / mutexes you will prevent it from happening but, after adding 5 threads to process data from a queue, there is no performance improvement because threads have to wait each-other. It was a design fault, to continue increasing performance I had to add more queues with different semaphores so the threads wont collide so much, so that brings me to the last version:



<Version Number 0.1.12:>


<867 Clients connected at the same time, everyone constantly moving sending data to the server, 25 incoming packets /s per client, total, +2.000 incoming messages processed/s,  peak:18.000 messages SENT in a second, that is like 18 packets /millisecond, latency/lag for the clients from 49ms to 113ms average 70-80ms>



Classes:

  • cSockServer: Stores global data , a vector to store all the clients connected, server socket, etc...
  • cSockClient:Stores data for every client such as socket to communicate
Threads:
  • 1x Master thread: Master thread listen for the clients and assigns a new socket to everyone.
  • 2xProcessor threads:It processes the data into the input queue and updates wold data
  • 1xUpdater Thread: inserts clients with updated data to a queue to update
  • 4xUpdaterQueues:it gets the client UID from the UpdaterQueue and check which clients are near and need to get an update state, so it inserts the outgoing data to the Pool of Output queues
  • Pool of Sender threads:The thread gets data from the Pool of Queues and Send data to the clients
  • 1xListener Thread/Client:listen for incoming data and inserts it into the Input queue.
Queues / vectors:
  • Clients vector:Here I store clients data (sockets, UIDs, etc)
  • Input queue:One in the server, used to store incoming data
  • <vector>Pool Output Queue:It can handle many queues so if the client number rise, you can add more queues to prevent thread collisions.
  • <vector>Pool Sender thread Queue: Used to store / add Sender threads dynamically.
Good things of the design:
  • Finally threads start to unleash their power, as many threads / output queues you add, as many users can handle, 867 clients (BOTs) are starting to be something good for a server....

Bad Things of the design:
  • No optimized at all, there are many parts in the server that could change to make it work smoother, but for didactic purposes, I wont change them at the moment.
What I learned from this version:
I have learned to be very careful with the threads, many threads can access to a variable and read from it and processing power will go up, but when writing data you are forced to use semaphores, so speed stops increasing after a certain number of threads.

I added a command for the server that was "AddPower" it adds one output queue and 5 sender threads, so you can adjust performance, but speaking with a friend he told me that I could automate it so automatically it added more queues /threads, so I did! checking if the queues were filled and needed to be processed faster was easy, and the result is the server you have in the picture absorving 867 clients data....

Thanks Jhonny D!

See you soon in the MMORPG series....

Friday, November 18, 2011

Debian Versus Kubuntu Versus Windows 8

Debian 6.03

Kubuntu 11.10

Windows 8 beta developer preview

In the last weeks I have tried many "new" OSes, the first one was Kubuntu 11.10:

After the decision from the Ubuntu team to use Unity in the standard distro 11.04 I have been waiting to see if in the 11.10 version all the mistakes have been removed, unfortunately I had exactly the same feeling that with the previous version...

One of the things I like from Linux is the freedom: freedom to choose what do you want to install and how to configure it to adapt to your personal tastes and needs

With the infamous Unity I feel like if I was a toy inside a Box: I can see beautiful glitter-filled walls, but I can't see anything else!, I thing that when in your process table Xorg is taking MORE CPU than your mmorpg server, something is completely wrong..

I downloaded and installed Kubuntu 11.10, hell I don't like windows-style from KDE but I was so disgusted with regular "Unitybuntu 11.10" that I decided to try it... now I regret I didn't went for Debian before..

Debian is the mother of Ubuntu, and many other Linux flavors, but I have been always afraid to download the tons of gigabytes the full distro uses, but when I entered www.debian.org last day I realized the network installer only occupied like 400 MB, so I downloaded , burned and installed it..

When I did I felt like my first times with Linux (with Slackware), everything was not made "for dummies", you had to set up many things, like repositories to be able to install apps, but well after goggling a bit I was able to install all the tools I use day by day....

It is not as beautiful as Ubuntu or Kubuntu but now my CPU cycles are used for my apps, not for openGL....


I downloaded today Windows 8 beta developer preview and installed it, after all the things I have heard from it I was almost sure it's gonna be very different from Windows 7, but  all the people that has been MS OSes since a few years ago will realize it shares many things from previous versions, the feeling I got from it is that it was completely designed not for pcs, but for Tablets... yes, forget about pcs, the interface is made so you can use it with a touch screen...

Another thing is forget to use it with any computer with less than a 2 dual core fast (2Ghz+ processor) with 2 GB RAM, I installed it in a virtual computer and it took 5 minutes to boot using one core from my I5 core processor (3.2Ghz), assigning the 4 cores to Windows made it boot in "only" 2 minutes... OMG! I hope MS optimize it.. or get ready for a "Vista 8"....

Well I have to test it more but the first feeling is Microsoft wants to change mind of the users.. again, time will say if they are right...


Well , enough OS review for today..

See you!

Tuesday, November 15, 2011

So I want make an MMORPG, Where do I start from? PART 1

That is indeed a good question, asked so many times and answered many times too, in many sites the answer is like:

<If you have a team>
  1. Get a team: coders + artists + world designers +well like 10 persons.
  2. Get ready to expend 2 years (at least) on it
  3. Pay big amount of money to the ISP
  4. Have a design document
<Lone developer>
  1. Forget about it :(
 What can I add to that? I basically decided to made it no matter how hard it was; I'm not somebody that has never programmed and think that their "RPG maker experience is enough", I'm not asking how to make it because If you are asking that, you probably are so far from the objective you desire that you wont get it never.

I tried to divide the BIG puzzle into small pieces, c++, SDL, SDL_image, SDL_ttf, SDL_NET, SDL_thread, Gimp, MYSQL....

With those pieces I made some bigger ones: A tileset, a simple game engine, game states, player creation process, a simple chat server....

And now it comes the good thing, I got a Simple (RPG DEMO) server with a client, I didn't made it on time (1 year was my objective), but now , after millions of doubts I know I will finish the game...

My objectives now are:
  1. Start a series of posts explaining how I did it.
  2. Clean Server / client code and upload them (Yes, I'm going to release it soon)
  3. Set up MYSQL server
So first thing first:

Q:What do I need to learn to send / receive date across the network?
A:Network sockets

Q: How does network sockets work?
A: Network sockets handles data send/received to an IP network, they are both used by TCP (Connection oriented ) and UDP (Connectionless oriented), in the server you "open" a socket to listen for incoming data, open a socket means bind the program to a particular IP port of the computer, so we could open a socket at port 80 to create a web server, for example, when we create a server socket it waits until a Client machine (program) connects to it, then we create a client sockets that is going to actually communicate with the client. The clients just open a client socket and establish a connection with the server socket.

Q:Why do I need threads?
A: Threads are used to do many things at the same time, for example, a Client for the MMORPG, could have a thread to draw the images on the screen while another one sends/receives network data , the server could have one thread (maybe more?) to handle network data, another one for the AI, another one for Environment events... In the modern multi-core computers, it's a way to use 100% of the processor power

Q:Why are you using SDL_NET? isn't it an ancient library?
A:It is old, but network sockets are older and are still used today (and probably are going to be used for many, many years), just thing the new IP protocol (IPv6) uses them too... SDL_NET has other advantages too, it can be used in a multi-platform environment (I use it in my client and I can compile it under windows / Linux without touching a single line from the code to make it work :) ), finally it is a low-level library so you feel you have the control over what you are working, there are libraries made upon SDL_NET that add things (NET2 uses multi-threading for example), but you have less control about what is happening, another problem is find documentation , SDL_NET is so small that when you read the manual , you realize how easy is to use it.

<More Q/A soon...>

In the next post: Server code and explanations..

JB

Friday, November 11, 2011

RPG Client Alpha!!!

<Client V0.11>

<Client V0.1>
<Doesn't it looks nice??>


So after two weeks fighting against the elements I have been able to connect my Rpg Demo with the chat server (and basically modifying all the code), but now you can move around with your own player...


You can't do much things, in fact you can just MOVE, but that's exactly the base where I wanted to start from.


I have uploaded the Windows version binaries so basically everybody (windows /linux + wine) can test it, just go to the downloads page and get it!

For alpha testers: To test it, you are going to need an IP number, PM please so I will tell you...


See you



Saturday, November 5, 2011

A Simple chat server, code uploaded...

<A chat server / client>


I've just uploaded the full code for the simple chat server and client projects, it is a very simple project, but shows the core needed to create a server including multi-threading and connections /disconnections from clients.

At the moment the clients can do:
  • Send messages to other clients.
  • Send private messages to another client (/priv nick message)
  • Ask for the list of connected users (/List)
  • Change nick (/nick newnick)
  • And of course, exit the server (/quit)
I don't have plans to upgrade the chat server, instead I'm going to adapt it so many players can connect with a client (rpg demo 4) to the server and anybody can walk around and chat.... That is my next milestone, when I achieve it I'll enable the fights to spice it a little ;)

JB

Monday, October 24, 2011

New Downloads / Windows Binaries

Hello!

New downloads!

<One year ago I started this project with many objectives, one of them was to make it multi-platform so yesterday I decided to compile my projects under Windows, or at least try to do it...>

<And here it comes the ingredients for my Windows recipe:
  1. A virtual machine emulator (a.k.a. Virtualbox ), Somebody will prefer a dual-boot configuration or just Windows, well, it's up to you...
  2. A Windows installation disk, you have one, right? (Important: First, clean the dust)
  3. Code::Blocks 11.05 compiler + minGW (Install, Next > Next > Next > Next > Finish.... Windows is SO user-friendly...)
  4. An assorted mix of libSDL libraries (SDL, SDL_image,SDL_ttf,SDL_net): Download, extract, and then mix them so you put all \include and all \lib files together, and of course the DLLs too.
  5. Download the sources too..
  6. If you want to compile them you will have to set up the compiler so it uses the sdl\include and sdl\lib paths, other way, it will simple refuse to work.
Another important thing is that you have to change all the includes:

#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "SDL/SDL_ttf.h"
#include "SDL/SDL_net.h"
#include "SDL/SDL_thread.h"  

In all the source files with:


#include "SDL.h"
#include "SDL_image.h"
#include "SDL_ttf.h"
#include "SDL_net.h"
#include "SDL_thread.h"  

(paths are a little bit different under Windows..)

<And well, that's it! after doing that I got the life game and the three rpg sub-projects working >

<I wanted to include the chat server / client project too, hey ! I really wanted to do, but I found an unexpected and silly problem, the chat server uses the std input / output for everything, I cout << what the clients "say" and get cin >> the clients input, it works fine under Linux, but under Windows, it redirects the output and errors too to the files "stdout.txt/stderr.txt", it is the normal behavior, if you are making a graphical project, you don't have the console, right? but what if you need it?>

<I have been goggling for solution and finally I found something that should work: > 


SDL_Init(SDL_INIT_VIDEO);    
if (ctt)    
{        
freopen("CON", "w", stdout);        
freopen("con", "w", stderr);        
fclose( ctt );     
}

<That was supposed to set the output again to console, I added the code, and when I executed the project under code::blocks, It magically worked again, so I happily rebuild the project...>

<And then I executed the resulting .exe, it opened a console window... (have I said it was black? completely black?) :(, that's when I decided I wont compile it for Windows ( at the moment), if anybody had found that problem and feels eager to help, I will really appreciate it...>

<In the next post, the chat server /client...>


See you
JB

Thursday, October 13, 2011

SDL_net / SDL_threads(1): The Threading beast, is it so dangerous?

A multi-threaded echo server....

<What is the most important thing beyond every mmorpg? is it the history?, maybe the fancy 3d graphics? nope... it is the network play!>

<When I started the project , one year ago my objective was to bring the game on-line, I just didn't thought how many new things I needed to learn, the C++ language , the libSDL  library, all the other extension libraries (SDL_image, SDL_ttf, SDL_net, SDL_thread, ...), how to use blogger... , the Gimp, etc, etc....>

<It has been a long trip, but now I have arrived where I wanted to be, to the network>

<On the top of the page there is an screen-shot showing my first networking demo, a multi-threaded socket server using SDL_net and SDL_thread>

<I start the server and then I can connect with telnet to the server, every thing I type on the telnet window goes to the server and it returns the message to the sender, maybe you can think it is something too easy, but let me show why it's important...>

<Here what you can't see is more important than what you see, that's the project structure:>


<I encapsulate all the network code into two classes: csockserver and csockclient, fist one opens an SDL_net server socket who is going to sit and wait for incoming connections, when it happens (new client connection), it creates a new csockclient and adds it to the vector, then the csockclient starts a thread and the thread wait for data incoming to the server for a client, when it happens it just echoes the data back to the client>

<it is a very simple way to handle data, a perfect base to start adding new features, now if we change just a few lines we will have a chat server, but threaded>

<I have remarked the thread thing because when I started to look for demos / tutorials to use SDL_net I basically found nothing related to using it with threads, the question is a server needs threads, we can't stop the server logic just to see if a client is sending data, and for the server I'm going to use more threads: (for example , for the A.I.) so many things can happen at the same time, making threaded code is very hard, because any small mistake is going to crash the server, make your computer leak memory, or even worse open a security hole....>

<I'm going to finish the next step (the chat server) and I will post the c++ code>

<Ideas / suggestions are always welcome>

<see you, in the chat>

JB

<B.T.W. Ogres are ugly, SDL_net + threads too, what could happen if you mix them?? ;)>

Sunday, October 2, 2011

Code::Blocks(17) RPG 4 - Rpg Demo working, Player creation end.

A preview before starting the networked part:



I have made so many changes in the code that it's gonna take very long to post all them, so what I'm going to to is to make a list with updated things:

<Engine class:>
  • I have added 3 fonts to the game, they only change in size so they can used for main tittles or the plain text in the game.
  • TextOut function to draw text.
  • IntOut function to draw numbers
  • FillRect to fill a rectangle with a color
  • Window function to switch between windowed / full screen mode
<Player class:>
  • Accel, Speed, Angle variables added
  • Now the player's point of view is defined by an angle, an the movement is based in that angle, when you press <forward> player speed will increase by it's accel value (to a limit) and move accordingly to that.
<Timer class:>
  • Needed two timers in the game so I found the easiest way to use them was to encapsulate into a class, now I have a timer for FPS calculation and another to regulate framerate.
<Text Input class:>

  • A new class used to grab input from keyboard and add to a string (Used to write player's name)
 <Game class:>
  • DrawMap: In that function I have made a small but very important optimization: it drawed all the tiles in the three layers in the map but that was a mistake because not all the three layers were filled, only the first one, so what I did was to check in 2nd an 3rd layer if the tile was empty and then if it isn't, draw it, a simple change that made the processor use change from 99% to 30%, not too bad!
  • ShowStats: a function to draw player stats (name, attibutes, skilss..)
  • DrawGUI:To draw player's life and magic points
  • DrawDir: To draw a single dot in player's point of view
<The textout and intout function had a nasty mistake that was leaking memory very fast, it was a bug hard to find but now it's corrected, the game only uses 3.4MB ram in my ubuntu 32bits computer.>



Monday, September 5, 2011

One thousand visitors, SDL_net and new features freeze.

Hello,

   Last Sunday my blog hit the 1000 visitors barrier, it's not a big number at all, but if I think in the small amount of people that dared to look at the the blog at the early beginning I can think on it like a personal success.

    It's not a gossip blog, not a dowload-movies blog or anything like that, in fact is a very specialized tech blog that has grown post by post, last three months have been good, only in those months I got more visitors than in all the previous 12 months, I have realized that the first objective I wanted to achieve is not going to be possible, I have learned many things in last year: SDL, C++ and to play a little bit with Gimp, and that took many time...


    I'm just about to finish the player creation progress, so I should be about to finish the first part of the project, I feel now more self-confident with my skills so many new ideas and features have grown in my mind to add to the rpg-thing game concept, the problem is that every new idea takes time to develop...


   So finally I have decided to stop adding new things, I'm going to just finish the rpg-demo and start with SDL_net, I have to test many things so I'm going to need pre-pre-alpha testers , if anyone dares I'm going to stay here, open-arms ...

See you soon

Saturday, August 27, 2011

Code::Blocks(16) RPG 4 - Game Menus






The game has two different menus, the start menu and in-game menu, the differences are the available options and what will happen when we choose them as seen here:

Start Menu:
  • NEW > Goto player creation
  • LOAD > Goto load game, Start game (Disabled)
  • EXIT > Quit game
Game Menu:
  • CONTINUE > Return to game
  • SAVE > Goto Save Game, Return Game (Disabled)
  • EXIT > Quit Game
For the menus I have created two images more:

Ball selector:



Menu Item:



I have used Gimp again to draw them, to draw the ball i just made a new, square shaped image, filled it with color FF,00FF (Pink) so i can apply later the colorkey, then i selected a circle and used the blend tool with orange and yellow colors.

Drawing the button was quite easy: Gimp > File > Create > Button > Simple beveled button, the only thing I made was to left the text empty so I can use the same button for all the menu items.

The logic for the menu is simple:
  • Define an "Option" variable, it will be which menu option is chosen.
  • Check the keyboard, and if we have pressed the following keys:
  1. Key up > decrease option 
  2. Key down > increase option
  3. Enter > execute action associated to the button (Change game state)
Now draw the menu:
  1. Fill with a color (grey)
  2. Draw menu tittle
  3. Draw menu buttons
  4. Draw the text into the menu buttons
  5. Draw the ball selector
Repeat until we press the enter key

      <"Game.cpp", Code for MenuStart:>
      void Game::MenuStart()    //Start menu
      {
      //MenuTittle ="START MENU";
      
      SDL_Surface* Button; //The menu buttons
      SDL_Surface* Ball; //The ball selector
      Button = IMG_Load("images/button.png");
      Ball = IMG_Load("images/ball.png");
      
      //The ball uses colorkey to display correctly
      SDL_SetColorKey(Ball,SDL_SRCCOLORKEY |SDL_RLEACCEL,SDL_MapRGB(Ball-> format, 255, 0, 255));
      
      
      SDL_Rect ButtonPosition ,BallPosition;
      int i; //An iterator for the loop
      int Option=1;//To select items
      
      //startx, starty Used to display images
      int startx = ((myengine.ScreenX / 2) - (Button->w/2) );
      int starty = (myengine.ScreenY / 2) ;
      
      
      bool done = false;
          while (!done) // will loop infinite times until we set done = true
          {
       SDL_Event event;
              while (SDL_PollEvent(&event))//Check new events
              {
                  // check for messages
                  switch (event.type)
                  {
                             // exit if the window is closed
                  case SDL_QUIT:
                      done = true;
                      break;
      
                      // check for keypresses
                  case SDL_KEYDOWN:
      
      
              // Down key
              if (event.key.keysym.sym == SDLK_DOWN)
              {
                 Option++; //Move down ball selector
                  if(Option>3)Option=1;
                  break;
              }
      
      
             //Up key
             if (event.key.keysym.sym == SDLK_UP)
             {
                   Option--;//Move up ball selector
                  if(Option<1)Option=3;
                  break;
             }
      
             //Return pressed
               if (event.key.keysym.sym == SDLK_RETURN)
             {
                 switch (Option)
                 {
                     case 1://NEW
                     myGameState=CREATEPLAYER;
                     break;
      
                     case 2://LOAD
                     myGameState=LOAD;
                     break;
      
                     case 3://EXIT
                     myGameState=OUTRO;
                     break;
      
                 }//switch option
                 done = true;
                 break;
             }//if
      
             //Exit game
             if (event.key.keysym.sym == SDLK_ESCAPE)
             {
                 done = true;
                 break;
             }
                  }//switch
              }//while
      
      myengine.FillColour(100,100,100);//Fill with grey
      
      myengine.SetTextColor( 0, 0, 255 );//Blue color
      myengine.TextOut(startx -50 ,100,"START MENU",3);//Menu tittle
      
      for (i=1;i<4;i++) // draw 3 buttons
      {
      ButtonPosition.x = startx; // X
      ButtonPosition.y = starty + (i*40); // Y
      ButtonPosition.w = Button->w;
      ButtonPosition.h = Button->h;
      
      SDL_BlitSurface(Button, NULL, myengine.screen, &ButtonPosition);//Draw button
      }//for
      
      BallPosition.x=startx -Ball->w;
      BallPosition.y=starty + (Option*40);
      BallPosition.w=Ball->w;
      BallPosition.h=Ball->h;
      
      SDL_BlitSurface(Ball, NULL, myengine.screen, &BallPosition);//Draw ball selector
      
      //Draw text for the options
      myengine.TextOut(startx + 10,starty + 50,"NEW",1);
      myengine.TextOut(startx + 10,starty + 90,"LOAD",1);
      myengine.TextOut(startx + 10,starty + 130,"EXIT",1);
      myengine.Flip();
      
      myengine.Wait(1);
        }//End while done loop
      
      //Free surfaces Before finishing
      SDL_FreeSurface(Button);
      SDL_FreeSurface(Ball);
      }
      

      <"Game.cpp", Code for MenuGame:>
      void Game::MenuGame()    //In-Game menu
      {
      
      SDL_Surface* Button; //The menu buttons
      SDL_Surface* Ball; //The ball selector
      Button = IMG_Load("images/button.png");
      Ball = IMG_Load("images/ball.png");
      
      //The ball uses colorkey to display correctly
      SDL_SetColorKey(Ball,SDL_SRCCOLORKEY |SDL_RLEACCEL,SDL_MapRGB(Ball-> format, 255, 0, 255));
      
      
      SDL_Rect ButtonPosition ,BallPosition;
      int i; //An iterator for the loop
      int Option=1;//To select items
      
      //startx, starty Used to display images
      int startx = ((myengine.ScreenX / 2) - (Button->w/2) );
      int starty = (myengine.ScreenY / 2) ;
      
      
      bool done = false;
          while (!done) // will loop infinite times until we set done = true
          {
       SDL_Event event;
              while (SDL_PollEvent(&event))//Check new events
              {
                  // check for messages
                  switch (event.type)
                  {
                             // exit if the window is closed
                  case SDL_QUIT:
                      done = true;
                      break;
      
                      // check for keypresses
                  case SDL_KEYDOWN:
      
      
              // Down key
              if (event.key.keysym.sym == SDLK_DOWN)
              {
                 Option++; //Move down ball selector
                  if(Option>3)Option=1;
                  break;
              }
      
      
             //Up key
             if (event.key.keysym.sym == SDLK_UP)
             {
                   Option--;//Move up ball selector
                  if(Option<1)Option=3;
                  break;
             }
      
             //Return pressed
               if (event.key.keysym.sym == SDLK_RETURN)
             {
                 switch (Option)
                 {
                     case 1://CONTINUE
      myGameState=MAINLOOP;
                     break;
      
                     case 2://SAVE
                     myGameState=SAVE;
                     break;
      
                     case 3://EXIT
                     myGameState=OUTRO;
                     break;
      
                 }//switch option
                 done = true;
                 break;
             }//if
      
             //Exit game
             if (event.key.keysym.sym == SDLK_ESCAPE)
             {
                 done = true;
                 break;
             }
                  }//switch
              }//while
      
      myengine.FillColour(100,100,100);//Fill with grey
      
      myengine.SetTextColor( 0, 0, 255 );//Blue color
      myengine.TextOut(startx -50 ,100,"GAME MENU",3);//Menu tittle
      
      for (i=1;i<4;i++) // draw 3 buttons
      {
      ButtonPosition.x = startx; // X
      ButtonPosition.y = starty + (i*40); // Y
      ButtonPosition.w = Button->w;
      ButtonPosition.h = Button->h;
      
      SDL_BlitSurface(Button, NULL, myengine.screen, &ButtonPosition);//Draw button
      }//for
      
      BallPosition.x=startx -Ball->w;
      BallPosition.y=starty + (Option*40);
      BallPosition.w=Ball->w;
      BallPosition.h=Ball->h;
      
      SDL_BlitSurface(Ball, NULL, myengine.screen, &BallPosition);//Draw ball selector
      
      //Draw text for the options
      myengine.TextOut(startx + 10,starty + 50,"CONTINUE",1);
      myengine.TextOut(startx + 10,starty + 90,"SAVE",1);
      myengine.TextOut(startx + 10,starty + 130,"EXIT",1);
      myengine.Flip();
      
      myengine.Wait(1);
        }//End while done loop
      
      //Free surfaces Before finishing
      SDL_FreeSurface(Button);
      SDL_FreeSurface(Ball);
      }
      
      

      <Now the game is starting to have what we would expect to find in a game, intros, menus.. in the next post the main game loop> 

      Monday, August 22, 2011

      Code::Blocks(15) RPG 4 - An intro screen



      <I will show how I did two things: the intro / splash screen and the outro, before starting I have to say that an intro screen is very important because it is like a business card: The sign from your game, obviously I'm not going to expend a week to make a 3D- synthesized intro but I will include it into the game so anybody can make their own, feel free to play with it>

      <My intro probably is the easier one you can do, I just made an Image with the gimp "File" > "Create" > "Logo" > then I chosen a marble texture, replaced the text and voilĆ”!:>

      <Intro image, saved as "tittle.png">


      <Then what I did was to make the background to fade in from black to white while I was showing the tittle image, to do so I just made a for loop with an integer variable "i" and filled the background with that value from {0,0,0} to {255,255,255}, finally I added a small delay (10ms) every frame to make it a little slower>

      <"SplashScreen" method:>

      void Game::SplashScreen() //Splash /Intro Screen
      {
      
      SDL_Surface* Tittle; //A surface to load intro image
      Tittle = IMG_Load("images/tittle.png");
      int i;
      for (i=0;i<255;i++)
      {
      myengine.FillColour(i,i,i); //Will fill the background from color {0,0,0} (black) to {255.255.255} (white)
      SDL_Rect end; //To set the intro image position
      end.x = (myengine.ScreenX / 2) - (Tittle->w/2); // X
      end.y = (myengine.ScreenY / 2) - (Tittle->h/2); // Y
      end.w = Tittle->w;
      end.h = Tittle->h;
      
      SDL_BlitSurface(Tittle, NULL, myengine.screen, &end);//Blit the intro image
      
      myengine.Flip();
      SDL_Delay(10); // slow down the process so we will actually se something on screen
      
      }//For
      
      SDL_FreeSurface(Tittle);//Clean memory
      
      myGameState = MENUSTART; //Go to start menu
      }
      

      <for the outro I just swapped the colour order from (0 to 255) in the intro to (255 to 0)  in the outro so it faded from white to black>

      <"OutroScreen" method:>

      void Game::OutroScreen()//Splash Screen
      {
      
      SDL_Surface* Tittle; //A surface to load outro image
      Tittle = IMG_Load("images/tittle.png");
      int i;
      for (i=255;i>1;i--)//Will fill the background from color {255.255.255} (white) to {0,0,0} (black)
      {
      myengine.FillColour(i,i,i);
      SDL_Rect end;
      end.x = (myengine.ScreenX / 2) - (Tittle->w/2); // X
      end.y = (myengine.ScreenY / 2) - (Tittle->h/2); // Y
      end.w = Tittle->w;
      end.h = Tittle->h;
      
      SDL_BlitSurface(Tittle, NULL, myengine.screen, &end);
      myengine.Flip();
      SDL_Delay(10);// slow down the process so we will actually se something on screen
      
      }//For
      
      SDL_FreeSurface(Tittle);//Clean memory
      
      myGameState = END; // It does not needs an explanation, right?
      }
      

      <In the next post: Game menus..>

      Thursday, August 18, 2011

      Code::Blocks(14) RPG 4 - More classes , Game states and a few tweaks more



      <In this post I'm going to create the basic structure of the game, until now I had almost all the code included in the "rpg.cpp" file, but it was starting to get too big. I knew i needed to do a few things:>
      1. Clean up code, separate it into smaller parts.
      2. Create a Game State structure
      3. Use the new tileset!(see picture above)
      4. Create a folder to store images, move all references to the images to the new folder.
      <Before starting with the updates to the code I'm going to explain what the game states are and what i expect to do with them>

      <The best way to understand it is to look at this diagram:>
       <We have many "Screens" that represent different game states, in every game state the game acts in a different way (different input, output and logic), what we need is to have a way to store where the game is, so we can launch the code that will handle that particular state>

      <At the moment that's the project structure:>





      <To create the game states and to divide the code into smaller parts, we are going to change the project structure to:>

      <Now the "main" function include all the code,  how i made the changes? First I created a file "gamestates.h" that is basically an enum to know in what state the game is:>

      <File "gamestates.h">

      enum GameState { //Enumerates the game states
          INTRO = 1,
          MENUSTART = 2,
          LOAD = 3,
          CREATEPLAYER = 4,
          MAINLOOP = 5,
          MENUGAME = 6,
          SAVE = 7,
          OUTRO = 8 ,
          END = 99};
      
      

      <File rpg.cpp has been totally rewritten:>

      #include  //SDL library
      #include  //+SDL_image library (I use it for loading .png files)
      
      #include "game.h" //Core game class
      
      int main ( int argc, char** argv ) //when you use a SDL c++ app you have to initialize main that way
      {
      
      Game mygame; //Create an Instance of Game, Loads default values
      
      mygame.myGameState = INTRO; //We start with the intro screen
      
      bool done = false;
      while (!done) //Loop infinite times until done
      {
      
      switch (mygame.myGameState)
      {
      case INTRO: //Intro screen
      {
          mygame.SplashScreen(); //Shows an intro Splash Screen
          break;
      }
      
      case MENUSTART: //The first menu (new game, load...)
      {
          mygame.MenuStart();
          break;
      }
      
      case CREATEPLAYER: //Player creation process
      {
          mygame.CreatePlayer(); //Player Creation Process
          break;
      }
      
      case MAINLOOP: //Game main loop
      {
          mygame.MainLoop();//The main game loop
          break;
      }
      
      case MENUGAME: //In game menu (save game...)
      {
          mygame.MenuGame();
          break;
      }
      
      case OUTRO: //Outro screen
      {
          mygame.OutroScreen();//The main game loop
          break;
      }
      
      case SAVE: //Save game
      {
          mygame.SaveGame();
          break;
      }
      
      case LOAD: //Load Game
      {
          mygame.LoadGame();
          break;
      }
      
      case END: //End game
      {
          done = true;
          break; //exit switch , end game
      }
      
      } //switch
      } //while
      
      return 0; //Everything is ok
      
      }//End main
      
      

      <Now it just contains a game class instance and a simple switch to select the game state and execute the right code (clean and neat), the game class is declared here:>

      <File "game.h":>

      #ifndef GAME_H
      #define GAME_H
      
      #include  //SDL library
      #include  //+SDL_image library (I use it for loading .png files)
      
      #include "engine.h" // The simple engine class
      #include "cplayer.h" //The player class
      #include "cmap.h" // The Map class
      #include "gamestates.h" //The Game states Enum
      #include 
      
      #include  // I use it to work with text streams
      
      using namespace std;
      
      //Class Game, i have moved everything
      class Game
      {
          public:
      
      
      
      GameState myGameState ; //used to know what we should do at any moment
      Engine myengine; //Create a object from the type "Engine"
      std::stringstream text; //Variable used to display text
      Uint8 x,y; //variables used to travel across the map array
      cmap mymap; // Our map class
      cplayer Hero; //Our player class
      //cmenu mymenu; //Our Menu Class
      Uint8 *keys;
      SDL_Rect Camera;
      
       char* MenuTittle; //The menu tittle
       vector MenuItems; //The menu items
      
              Game();
              virtual ~Game();
              void SplashScreen();
              void OutroScreen();
              void MenuStart();
              void MenuGame();
              void CreatePlayer();
              void MainLoop();
              void SaveGame();
              void LoadGame();
      
          protected:
          private:
      };
      
      #endif // GAME_H
      
      

      <Notice I moved all the variables as properties into the new class, and functions now are methods, notice too we have achieved two objectives: clean the code and split it into smaller parts, it is easier to understand and implement too, next objective is to code game.cpp >

      The first function, the class initializer is this:
      file "game.cpp"

      Game::Game()//Initialize Game class instance
      {
      myengine.SetVga(800,600,32,true); //Start graphics mode
      myengine.LoadTileset("images/tileset3.png"); //Load the image tileset to a SDLSurface
      
      
      //Set starting position and speed for the player
      Hero.SetX(110);
      Hero.SetY(310);
      Hero.SetSpeed(10);
      
      //Set default values for the players
      Hero.SetName("Conan");
      Hero.Defaults();
      Hero.CalculateVitMag();
      Hero.MaximumAttributes();
      
      //Ser camera starting offset
      Camera.x=1;
      Camera.y=1;
      Camera.w = myengine.ScreenX;
      Camera.h = myengine.ScreenY;
      }
      

      In the next posts I will show all the other methods.

      Tuesday, August 16, 2011

      Creating an RPG player




      <We've got a player and we can move the player around a tile-map but we need the most important thing in a RPG game,  the player creation process>

      <There are hundreds of methods to create RPGames , but i have chosen to use a percentile method because it's quite easy to implement and it fullfills all my game needs>

      These are the rules for my game:

      SKILLS:
      • In this method the skills are a value from 0 % to 100 % (can get higher, but that would take ages for the player to achieve and it does not give an actual advantage) that represents the chance to successfully use a skill.
      • Every skill is linked to an attribute.  
      • Skills grow when you use them or when using skill points.
      • When a skill reaches 70%(Expert) and 90%(Master) the player earns two skill point.
      • Skill points are special, player start with skill points and get new ones when using skills.
      • Skill points can be used to increase a skill (Every point expend increases a skill 10% up to 50% maximum) or to learn a new skill to a 25% level (To do so player needs to find an NPC with the desired skill with a level of 90% or higher, and usually pay a fee that will depend on the skill).
      • A skill can have from zero to two parent skills, those are skills player MUST already know before learning the skill, most of the skills will finish forming a kind of skill tree, but a few ones are free to anybody.
      • When there is a skill check there are 4 possible results (As an example I will use a warrior with melee at 70% attacking an Orc):
      1. Skill has failed: When player rolls a skill and gets a value higher than it's skill (example: 83 > higher than 70%) this means player has failed to hit the Orc.
      2. Critical failure: When player rolls a skill and gets a value from 96 to 100 , that will happen even if the player has a skill level higher than 95 (for example 135%), so there is always a small (5%) possibility to fail a skill, there are not guaranteed skills in the game except event-driven ones (special events)
      3. Skill has worked: When a player rolls a skill and gets a value equal or lower than his/her skill (warrior rolls 43, lower than 70% > Orc has been hit)
      4. Critical success: When a player rolls a skill and gets a value equal or lower than his/her skill divided by 10 (in the example, the warrior has 70% melee, divided by 10 > 7% critical chance so if it rolls 1-7 the Orc is going to get a critical hit...) , when a critical success, the effect of the skill is doubled , for a melee skill for example, double damage .
      • Every skill has an upgrade level, the upgrade level is an integer value starting at 0 that grows by one very time a player successfully uses a skill.
      • When the upgrade level gets higher than the current skill level, the skill level increases by one, and the upgrade level goes again to 0, in the example the warrior has a melee skill at 70% with an upgrade level 70, the warrior uses the melee skill again an rolls 35 (success) so upgrade level goes to 71, it is greater than melee skill so melee skill goes to 71% and upgrade level to 0.
        ATTRIBUTES:
        • The attributes of the player come in a value from 5 to 15 (To prevent too high/ too low values).
        • All attributes start at 10, that is the "medium" attribute value, if you've got an higher or lower value, the chances to use skills based in that attribute will be greater/lower.
        • The player can remove points from one attribute to increase another, but it will never be higher than 15 or lower than 5.
        • When finishing the player creation process, every attribute is doubled and stored, that is the maximum value a player can get an attribute ever, so it is very important to choose how to distribute the attribute points at the start of the game thinking of what kind of player you want to be.
        • All players have these attributes:
        1. Strength:The brute force, increases the damage made using melee weapons.
        2. Dexterity:It is both the agility and how fast the player is.
        3. Endurance:The endurance, pain and venom resistance
        4. Size:Physical size, modifies life points and armour prices
        5. Intellect:Mind power, basically modifies all mind related skills starting from literacy (write/read) to magic skills
        6. Power:The player's soul strength, it increases resistance to special magic attacks (disintegrate like spells) and versus negative plane creatures (such as undeads (zombies, ghosts), daemons , daemonic weapons (items)), it modifies to the amount of followers a player can have (NOTE: Followers are bound undeads / daemons / beasts)
        • There are some special stats that depend on the attributes:
        1. Life / Vitality points: It is based in Size*2 + Endurance
        2. Magic points:It is based in Power*2 + Intellect
        3. Carry capacity: It is based in strength + size
        GENDER:

        In the game gender affects attributes:
        • Male players: Strength +1
        • Female players: Dexterity +1
        <Before anybody complains about it, the gender rule is set to make the game more fun, not to discriminate anybody in anyway so it has nothing to do with sex rights, it is just a game!>

         RACES:

        Players can choose to play with the following races:

        • Humans: Good in almost everything, they have no special modifiers <Humans were the stronger civilization in my game, they became so powerful that they tough were gods, opened doors to distant planes, made dark pacts with even darker gods but finally the doors were left open, when the negative plane creatures started to get into the world it was too late to try to close it..., nowadays humans just fight to survive>
        • Midgets: Small sized humans, they are quite small and notably faster too (Size -2, Dexterity +2), <some people say they are the thieves nation, but nobody ever has proven it>
        • Mountain humans: Rude, strong but not very intelligent (Strength +2 , Intellect -2) <It is said that when the first humans had their first encounter with the Mountain giants the natural selection started to play again, after centuries they have become a stronger race>
        • Forest nation:  Fast, very intelligent humans, but very weak (Dexterity +1, Intellect +2, Strength -3) <Nobody knows when those humans started to live in the deepest, forgotten forests, but everybody knows what they do: Look for arcane knowledge and dark secrets...>
        • Half giants: Pure muscle, very big, slow and definitively dumb (Strength + 3, size +3, dexterity -3, intellect -3)<somebody will tell they are Huge Mountain Humans, others will tell they are small giants, either way they are the most unbalanced race to play>.
        <Note about the races: Notice that if you add all the modifiers from a race, it will always become 0, even Half giants!, it is the only way to try to balance it, another important thing is that after modifying the attributes, the gender and race selection, the maximum and minimum attributes you can get is 19 and 2, attributes very high can make a warrior / wizard very strong (only in the super-attributes based skills), but they will have a few attributes so low that it will be almost impossible later in the game to use anything else, humans are not the stronger, faster or more intelligent , but they can use both swords and books >

        <In the next post, i will iexplain the player creation process in the game>

        Monday, July 18, 2011

        An Ubuntu Server (1/X)


        <Open case view>

        <I have been playing around with the tiles and the maps for a while, it was good but if i have to finish the project in time , it's the right moment to make my own server to test SDL_Net >


        <First i needed to set up a server, probably you will think i was going to use a dual xeon computer with terabytes of hard disk .... from my experience with the servers and the power needed to run the app i don't need so much hard, in fact i have decided to run it in a quite old computer, that's the server configuration:>
        • Intel 3.06Ghz CPU
        • 1GB RAM
        • 2x9GB SCSI HDDs
        • 100 MBs LAN
        <The most important thing in a server is data redundancy , if the server power supply fails, you will have a server down, but you can bring it to live just replacing it, But what will happen if the hard disk crashes?, just guess.... so i decided to set up a software RAID 1 device with two SCSI hard disks, the processor and RAM are weak for a desktop gamer, but i think they are going to handle the expected amount of users, at least in the beginning>

        <Dual SCSI disks>


        <Now into the software, the final server configuration is going to use the Ubuntu Server edition but at the moment i need to debug and compile the project in the server, so I'm going to use the Ubuntu 10.10 Alternate edition instead of the server one>

        <You may ask "Why to use the 10.10 version when there is a new version (11.04)?" , it is indeed a good question, and the quick answer is "Unity"... for all the people that have worked with Ubuntu from a few years ago , you are used to the Gnome desktop manager, so you were not forced (in the past) to use a (quite) bloated desktop manager like KDE, I'm not telling you to don't use KDE, it's good of course, but for me it smells too much like MS products...., but now Gnome has decided that to use the desktop manager you are going to need a powerful opengl card (maybe it's ok for a modern desktop computer), but it's not so ok for a server computer.., Unity tries to solve this problem, but if you have ever used the "Ubuntu Netbook Remix" you will know it's NOT a mature product, you have the feeling that is sort of mac OS/X clone, can't set up the desktop and bars the same way than in standard Gnome and finally i'm pretty sure it is much more slower than the (old) Ubuntu 10.10>

        <For me it's quite clear which o.s. to use, just go and get Ubuntu Alternate 10.10 and burn the cd to start installing it>

        In the next Post, installing wit Ubuntu Alternate, software RAIDs and more....

        Sunday, July 10, 2011

        FREE RPG - Tileset

        <Updated 25/October, please read the bottom>
        <Updated 25/July, added stairs, and cleaned a pair of things>

        Hello, finally I'm back again!!, and that's what I've been working on:


        RPG Tileset v1.0
        License: GPL (Read below about nethack tileset licensing)

        <Now I've got something to start working , it has taken me many , many time and i didn't had a big amount lately so what I've done to try to speed up the process was to start looking first at other's work...>

         <I watched many tilesets, found a few real impressives like the ones at lost Garden  but unfortunately they didn't were what i really need, then i started to search into the free to play rogue-like games, there are so many out there!, finally i saw the Nethack 32 graphical tileset>

        <Now it is when i ran into problems , the tiles were 32x32 pixels, and i'm using 100x100 pixels tiles, so i have to adjust every tile i imported from the nethack into mine's, other problems is that the nethack tiles had a "brick"background so i had to clean it pixel a pixel, so i could paint them using the transparent pink color to overlap images (SDL_ColorKey).>

        <I used the nethack tileset to import all the characters from the game, the players, the foes and the beasts too, and most of the items too, but i tried to draw the other things: i made the terrain and a few effects , there is still many work to do, but i really needed something to start working, promise I'll improve it!>

        <VERY IMPORT: Tileset LICENSING:>

        <Another important thing is i MUST give thanks to all the people that made posible to bring the nethack game to live and were so kind to share it to anyone (Please read the license), basically what it means is "You are permitted to modify NetHack, or otherwise use parts of NetHack, provided that you comply with the conditions specified above; in particular, your modified NetHack or program containing parts of NetHack must remain freely available as provided in this License Agreement. In other words, go ahead and share NetHack, but don't try to stop anyone else from sharing it farther. ", so thanks all the people again, remember that if you use the tileset for anything it MUST REMAIN under GPL, free to anyone..., that kind of things is what makes open source strong and made linux and so many programs to be available to the people....>

        <now i think it is time to stop chatting and start to explain my fight against the gimp and how i actually made the tileset:>

        I came from MS Windows , and my very first paint program was MS Paint, oh yes, the wonderful image editor!, since Windows 3.1 i have used it... ¿Time to upgrade right?

        I started installing the Gimp , i wanted to work with the gpl tools so from all the software i chosen it, it's a powerful but not so easy to start learning, anyway there are hundreds of tutorials to learn using it, just google for "gimp-tutorial" and you will see, in Ubuntu i just went to software center and searched for it.

        After installing the Gimp i created a new image, I made it 1000x1000 pixels in size, then i went to "Image" > "Configure grid" and i made a grid size of 100x100pixels (the size of an individual tile):



        Now i selected "View" > "Show Grid" and "View" > "Snap to grid"


        Then i filled everything with the transparent color (pink= FF00FF), notice we have the tileset ready to work, we just need to know how to organize the tiles:
        • I used the first two rows for terrain tiles
        • 3rd is used for a few terrain objects and magical effects
        • 4th is used for the players
        • 5th and 6th is used for misc. objects
        • 7th and 8th are monsters, and finally 
        • 9th and 10th are used for the gui icons
        There are still many missing tiles, for example I need stairs, a portal and many other things, so probably i will enlarge the tileset

        To draw the terrain tiles i just selected the tile and filled it with a texture, then i selected "Filters" > "Map" > "Make seamless" so they will fit correctly with each other.

        I imported the nethack tiles selecting them with the "Rectangle select tool" one a time, then copied it and pasted it into my tileset, then i needed to "Tools" > "Transform tools" > "Scale" to the size 100x100 pixels (32x32 pixels in Nethack), finally with the "Pencil tool" i cleaned all the background to the color "FF00FF" (pink).

        So basically that's how i filled 80% of the tileset, i drawed a few things, like GUI icons but explaining how i made them falls out of this tutorial....

        I would really appreciate any comments about this tileset (what will you add/remove / upgrade) I really hope this helps other people than me..., I hope too to post more advances in the rpg game too soon.


        A final Note: Many people has come here (in fact 100+ persons), for example you!, watched the tileset or downloaded it, but nobody has made any comment about it, it is a shame because if YOU don't say a word..

        • I don't know if people like it or find it useful.
        • I don't know if there are things that people would like to change /add / erase.
        • I'm not a magician , can't read minds, please help me to improve things.
        Thanks!
        JB

        Monday, May 23, 2011

        Stoping to order things.

        Hello!

                 I've got a good and a bad new:

                The bad one is that i have stopped posting in the last weeks because I've been really busy with many important (and not so important) things...

               The good thing about it is that i have realized that i should have done one thing before going any further into the tutorials: to make a decent tileset, it may look a trivial thing but it's not at all: there are many things in the game that need the graphics, so no graphics, no game.

              When i started to make the tileset, first i tried to use one of the many free tilesets wandering around the net, i started googling but after searching for hours i discovered a few things:

        1 -It is real hard to find good-quality tilesets.
        2 -Tilesets are very genre-specific, so i discarded many tyrian-zelda-pokemon-clones.
        3 -When i started to found rpg-tilesets , it was not like i could use straight the tilesets, i should need to adjust the size, clean the background so it has a transparent color, not bricks....

        Finally i have chosen to use the nethack graphical tileset to create my own one, in the next post i'll be showing it and how i did (part of the tiles, no credits at all to me)...

        bye

        Tuesday, April 5, 2011

        Code::Blocks(13) RPG 1 - The Hero has a Name!

        I'm back again!

        < In the previous tutorial i didn't made use of part of the features that come with C++ : classes, so it's time to use them to define and store data about our hero and the map, into the player class i want to define the player creation process, finally i want to create a Main Menu for the game...>


        I think I'm very ambitious with that post, but the objectives are:
        1. Create at least two classes: cplayer and cmap
        2. Define a Player creation process
        3. Create a Main Menu..
        <Step one: the classes>

        First let's start creating two classes: cplayer and cmap, to do that code::blocks has an assistant to design classes, so resuming from the code in the previous post we should select "File" > "New" > "Class":



        In the class name , write "cplayer", and then mark "Header and implementation shall be in the same folder", then press "Create":


        Select "Yes" to add the files to the project and...



        Press ok, so we will use files both to debug and compile the release project, we need to create a second class "cmap", so just repeat the steps,and save the project.

        Now let's start modifying the cmap class, we have two files cmap.h (header) and cmap.cpp (implementation), in the header we are going to define the variables and functions , so we are going to move the Uint8 Map[x][y][layer] to the class, we need too a pair of functions to get and set the values in the map array, so our cmap header will finally be:

        #ifndef CMAP_H
        #define CMAP_H
        
        #include  //SDL library
        
        class cmap
        {
            public:
                cmap();
                virtual ~cmap();
                Uint8 GetTile(int x, int y, int layer); //Get tile value
                void SetTile(int x, int y, int layer, Uint8 Tile);//Set tile Value
            protected:
            private:
            Uint8 Map[50][50][3]; //The map, now it has three layers
            int x,y;
        };
        
        #endif // CMAP_H
        

        Now we have to implement the functions in cmap.cpp:

        <cmap::cmap(creator)>
        cmap::cmap()
        {
            //ctor
            for (x=0;x<50;x++){ // Map size 50x50 tiles: 5000 x 5000 pixels
            for (y=0;y<50;y++){
                Map[x][y][0]=0; //clean the map layer 1 so everything is "0" >> "sand"
                Map[x][y][1]=63; //clean the map layer 2 so everything is "63" >> nothing
                Map[x][y][2]=63; //clean the map layer 3 so everything is "63" >> nothing
            };//end y for
         };//end x for
        
        for (x=2;x<5;x++){
            for (y=2;y<7;y++){
                        Map[x][y][0]=2; //A lake
                        Map[x+4][y][0]=1; //Grass..
            };//end y for
         };//end x for
        
        for (x=1;x<5;x++){
            Map[x][2][1]=8; //Trees
            Map[x][3][1]=10; //A road
        }; // end for x
        
        Map[5][3][1]=12; //A road
        Map[5][2][1]=14; //A road
        Map[6][2][1]=10; //A road
        
        Map[6][3][1]=9; //A volcano
        
        Map[3][3][2]=25; //Coins
        Map[4][3][2]=25; //More coins
        
        for (x=0;x<50;x++){
                        Map[x][0][0]=2;
                        Map[x][49][0]=2;
                        Map[0][x][0]=2;
                        Map[49][x][0]=2;
         };
        }
        
        

        <cmap::SetTile>
        void cmap::SetTile(int x, int y, int layer, Uint8 Tile) //Set tile value
        {
               Map[x][y][layer]=Tile;
        }
        

        <cmap::GetTile>
        Uint8 cmap::GetTile(int x, int y, int layer) //Get tile value
        {
                return Map[x][y][layer];
        }
        

        That's it! Now we have a simple class that will store the map data, notice that i've inserted into the creator the code to define a map.. it's not the better way to do that , but i wanted to show how we can separate code into classes , now we need to change a few things in the main program to use the new class, first we have to insert into rpg.cpp:

        #include "cmap.h" // The Map class
        

        So we actually use the class, now let's create a variable to use the map:

        cmap mymap; // Our map class
        

        Then i will erase the old Uint8 Map definition and the old map initialization, now everything is inside mymap, finally we have to update the map blitting functions to draw the map:

        myengine.BlitTileset(x *myengine.TileSize-Camera.x,y *myengine.TileSize-Camera.y,
        mymap.GetTile(x,y,0)); //Display map, layer 1
        
        myengine.BlitTileset(x *myengine.TileSize-Camera.x,y *myengine.TileSize-Camera.y,
        mymap.GetTile(x,y,1));//Display map, layer 2
        
        myengine.BlitTileset(x *myengine.TileSize-Camera.x,y *myengine.TileSize-Camera.y,
        mymap.GetTile(x,y,2));//Display map, layer 3
        
        

        Notice before i used Map[x][y][layer], now mymap.GetTile(x,y,layer), time to "Build and Run" the project to see what happens, if you have followed all the steps, you should get the same results than in the previous post, it's ok because we have just changed a variable with a class.

        We have to create the player class too, so let's move the PcX,PcY and PcSpeed to the cplayer class:

        <cplayer.h>

        #ifndef CPLAYER_H
        #define CPLAYER_H
        
        
        class cplayer
        {
            public:
                cplayer(); //Creator
                virtual ~cplayer(); //Destructor
                void SetX(int x);// Set player x position
                void SetY(int y);//Set player y position
                void SetSpeed(int speed);//Set Player speed
                void SetName(const char* name);//Set Player's name
                int GetX(); // Get player x position
                int GetY(); // Get player y position
                int GetSpeed();// Get player speed
                const char* GetName(); //Get player name
        
            protected:
            private:
            int X,Y,Speed; //X and y position, player speed
            const char* Name; // Player's name
        };
        
        #endif // CPLAYER_H
        
        

        I've added too the player's name variable, and the functions to get/set the values:

        <cplayer.cpp>

        cplayer::cplayer()
        {
            //ctor
            X=0;
            Y=0;
            Speed=0;
            Name="No Name";
        }
        
        cplayer::~cplayer()
        {
            //dtor
        }
        
               void cplayer::SetX(int x)
               {
                   X=x;
               }
        
                void cplayer::SetY(int y)
                {
                    Y=y;
                }
        
                void cplayer::SetSpeed(int speed)
                {
                    Speed=speed;
                }
        
                int cplayer::GetX()
                {
                    return X;
                }
        
                int cplayer::GetY()
                {
                    return Y;
                }
        
                int cplayer::GetSpeed()
                {
                    return Speed;
                }
        
                 void cplayer::SetName(const char* name)
                 {
                    Name = name;
                 }
        
                 const char* cplayer::GetName()
                 {
                     return Name;
                 }
        
        
        

        Now we return again to rpg.cpp, we have to add:


        #include "cplayer.h" // The player class

        So we actually use the class, now let's create a variable to use the player:

        cplayer Hero; // Our player class

        And initialize the values:


        Hero.SetX(110); //starting player's x position
        Hero.SetY(310); //starting player's y position
        Hero.SetSpeed(5); //starting player's speed
        Hero.SetName("The Karbarian"); //Player's name


        Keyboard input changes, to use the player's class:

        if (keys[SDLK_UP])Hero.SetY(Hero.GetY() - Hero.GetSpeed());
                    if (Hero.GetY()<1)Hero.SetY(1);
                    while (Hero.GetY()  <= (Camera.y )) Camera.y-=1;
        
        if (keys[SDLK_DOWN] ) Hero.SetY(Hero.GetY() + Hero.GetSpeed());
                    if (Hero.GetY()>4900)Hero.SetY(4900);
                while (Hero.GetY() +100 >= (Camera.y  + Camera.h ) )Camera.y+=1;
        
        if (keys[SDLK_LEFT] ) Hero.SetX(Hero.GetX() - Hero.GetSpeed());
                    if (Hero.GetX()<1)Hero.SetX(1);
                    while (Hero.GetX()  <= (Camera.x )) Camera.x-=1;
        
        if (keys[SDLK_RIGHT] ) Hero.SetX(Hero.GetX() + Hero.GetSpeed());
                    if (Hero.GetX()>4900)Hero.SetX(4900);
                while (Hero.GetX() +100 >= (Camera.x  + Camera.w ) )Camera.x+=1;
        

        And finally the blitting functions need to be adapted too so they use the player class:

        for (x=Camera.x/100 ;x<=Camera.x/100 + (Camera.w/100);x++){//Process map
            for (y=Camera.y/100  ;y<=Camera.y/100 + (Camera.h/100);y++){
        
               myengine.BlitTileset(x *myengine.TileSize-Camera.x,y *myengine.TileSize-Camera.y,
        mymap.GetTile(x,y,0)); //Display map, layer 1
               myengine.BlitTileset(x *myengine.TileSize-Camera.x,y *myengine.TileSize-Camera.y,
        mymap.GetTile(x,y,1));//Display map, layer 2
               myengine.BlitTileset(x *myengine.TileSize-Camera.x,y *myengine.TileSize-Camera.y,
        mymap.GetTile(x,y,2));//Display map, layer 3
               };
         };
        
        myengine.BlitTileset(Hero.GetX()  - Camera.x   ,Hero.GetY()  -Camera.y  ,16); //Display player
        

         Well, our player has a name and we want to show it, so that's what i'm going to make here:

        mycolor = {0, 0, 0 };
        myengine.SetTextColor( mycolor);
        myengine.TextOut(Hero.GetX()  - Camera.x  +50  ,Hero.GetY()  -Camera.y  ,Hero.GetName());
        

        We display player's name at his right side, it can be easily modified so the name moves to another side...




        <update>

        Post is getting way too big, I'm going to split it so it's going to be easier to follow..

        See you