Using the N3PMesh converter

Knight Online uses an internal file format called “N3PMesh” to store a lot of the game’s item meshes along with other various game meshes. A lot of these files are located in the “Item” folder found within the game’s install directory. You can think of every object in the game has having its own 3D mesh. In order for a object to appear in game we need to first know all the vertex information in order to draw the object using a 3D rendering library (in KO’s case it would be the DirectX library). A lot of the details aren’t necessarily important for this article but sometimes players would like to modify the 3D meshes in order to change how the objects look in game. I’m going to show you how to do this using the N3PMeshConverter.

Using the converter it is possible to convert .n3pmesh files into .obj files (allowing you to modify the appearance of the game’s weapons) and it can convert .obj files (along with other various formats) into .n3pmesh files. All this allows for you to export objects from the game, modify those objects, and import the modified objects back into the game.

In order to export an object you first must convert the .dxt item texture to a .bmp/.png image file using the N3TexViewer. Next run the following command using the command prompt (Windows Start Menu -> Search Bar -> Type “cmd” -> Press Enter).

This command will convert the .n3pmesh for the basic bow into a .obj file. Using the .obj and image file you can easily load the KO mesh into a 3D mesh editor like Blender.

 

In order to import the .obj file back into KO’s .n3pmesh format (presumably after you have made your modifications) use the following command (again via the command prompt).

Simply paste the new .n3pmesh into the KO content folder and the newly modified weapons mesh will appear in game!

 

Getting setup with the OpenKO project

I recently made a video on how to get setup with the OpenKO source code and another video explaining the basic structure and history of the codebase. Feel free to take the time and get the code running! If you have any questions feel free to send me an email (info@stephenmeier.net).

This second video explains a little about where the source code originates from and what major changes have taken place since I first started working on everything.

Kodev – Updating the UIQuestMenu

I recently made a video explaining how the quest menu GUI works for the game Knight Online. This is the first part in a two part series where we look at why these GUI components work the way they do and how we can use the GUI editor to help us to implement functionality for later versions. Part two for this series has already been recorded I just need to upload it! I hope to do that in the next week or so. If you have any questions or would like to suggest future topics for videos please email me at “info@stephenmeier.net”. Thanks!

EDIT: I was recently able to upload part 2! In the future I will try not to make the videos so long because they quickly become hard to upload.

 

SDL 2.0 Tutorial-06: Networking 3

In the last tutorial we setup a basic TCP server. In this tutorial we will start by modifying the server we setup and finish by writing a player client application. In order to write a client application with SDL 2.0 we will need a lot of the ideas which where presented in my first string of SDL tutorials (here). A lot of my personal preferences for setting up SDL have changed since writing those tutorials so instead of using code found within those tutorials I will be using a collection of C++ files I have settled into using (found here).

First let’s start with a few server-side modifications. Let’s start by adding a few extra packet flags:

Now we have a packet flag for starting and completing a quest, as well as a packet flag for getting the amount of time left until the quest is completed. Next we will update our server-side “RecvData” function:

What I have done here is removed the work this function was doing to grab the packet flag from the start of the incoming socket data. This is because when a socket is ready for us to process it may have several packets all lined together. Therefore the data buffer returned by “RecvData” may contain several packets depending on how quickly the client is sending packets to us; so any work “RecvData” does to grab the flag from the first packet doesn’t help us identify the packet flags for all the other packets possibly following the first. Therefore the extra work being done isn’t necessary at this level.

Next we will add a new function called “ProcessData.” This function will continuously run on each packet we find within the data buffer returned by “RecvData.”

This is where we do the work and grab the packet’s flag. Everything here should look similar to what we where doing before when the server found client sockets which were ready with information to be processed – except for the fact that we have added two extra flags. The “GETTIME” flag checks if the player is currently questing; if not then the time left on the quest is 0, otherwise the server sends the time left on the quest to the player. The other flag is the “QUEST” flag; this flag checks whether the client is currently questing and starts the quest if they aren’t currently in a quest.

The finial server-side update we make will be to the main processing loop. First let’s crank up how often we check for ready sockets:

If  num_rdy <= 0 then we do not have any sockets ready for processing so we enter the server’s idle tasks. Previously we were simply adding four wood to the client’s resource count continuously. This is quite a silly thing to do! Instead let’s check for whether a client has completed any quests and if so we’ll send out a quest completed packet and a wood update packet. In addition, we’ll continuously send out “GETTIME” packets to keep the client updated with the server’s timer.

And for the final server touch we’ll update the code which runs if there are sockets ready to be processed. Notice that how we handle the server socket (for new connections) isn’t changing but how we handle the client sockets is changing.

I am also keeping track of the number of packets which the server processes for each of the ready clients for debugging purposes. Now the client-side stuff isn’t that different when it comes to the network side of things. A lot of the helper functions we have server-side will have analogous client-server versions. Here is the client-side code in its entirety:

All the SDL graphics processing and input handling is being wrapped with the custom files I wrote and linked at the beginning of this post. If you find these posts helpful or would like me to dive deeper into a particular topic covered here please send me an email at “info@stephenmeier.net”.

network_pic00

SDL 2.0 Tutorial-05: Networking 2

In the last tutorial we finished with a hallow if-statement within our processing loop.

If there aren’t any sockets which we need to process (i.e. num_rdy <= 0 ) then we’ll loop over all the currently connected client sockets and perform any tasks which may be pending. This is basically the server’s chance to catch up with game state and perform any security checks. This will work well for a simple TCP game where the server and client need not be in sync the entire time. For something more real-time we would prioritize game state and perhaps use UDP instead.

For now let’s add four wood to the resource count for each connected client.

Remember this will run every second assuming there aren’t any sockets to be processed (i.e. num_rdy <= 0 ). Why am I saying it’ll run every second? It is because of the following function call:

The second argument to this function is 1000, which is the number of milliseconds this function will block while waiting for a socket connection.

Now, if there are sockets ready to be processed we’ll have to check whether it is a client socket or the server socket. If the server socket is ready then we likely have a new client connection. For the client connections we’ll have to check each one until we find the ones which are ready and then process the data that we have received from them.

First let’s handle the case when the server socket is ready:

Here the function  int AcceptSocket(int index); is a shorthand for accepting a new socket connection using  sockets[index] and  clients[index] . This function returns whether or not the connection was successfully accepted. Here is the function itself:

The function  void CloseSocket(int index); was presented in the previous part of this tutorial. After we accept the new client connection we also update the  next_ind variable so that we are ready for the next client connection. As it’s currently written, if a new client connects when the server is full then another client will be kicked to make room for the new connection.

Now let’s process any clients which might have data for us.

What we are doing here is looping over all the client sockets and checking to see whether a client is connected and whether that connected client has some information ready for us. We also want to make sure that we aren’t working harder than we have to by breaking out of the for-loop when  num_rdy == 0 ; because at that point we have processed all the ready client sockets so there is no point in checking any remaining client connections for information.

Once we know that we have a connected socket and that the socket have information ready for us, we fill a buffer with the data they sent us. This is what the  uint8_t* RecvData(int index, uint16_t* length, uint16_t* flag); function does for us:

This function gets data from  sockets[index] and returns a pointer to a new buffer. The in/out function arguments  length and  flag are the length of the newly allocated buffer and the packet flag for the information we are receiving from the client.

If the client sends us a request for the amount of wood they current possess (i.e. FLAG_WOOD_UPDATE ) then we reply by sending them a packet with the information they are requesting. To send information to the connected client we use the following shorthand function:

For debugging purposes the client can also shutdown the server with a  FLAG_QUIT . In the next tutorial we will write a simple client which will display the amount of wood the client current has. This amount will continue to increase because the server currently adds four wood each time it enters idle processing. Once we have achieved this we’ll add a “quest” button and timer on the client-side and a few more packet flags allowing the client to request the amount of time left on a quest and to start a quest. The server will check for when a quest completes and will increase the amount of wood for that client as a result.

Till next time!