Zimans

Members
  • Content count

    254
  • Joined

  • Last visited

Community Reputation

237 Neutral

About Zimans

  • Rank
    Member
  1. Revision control for games

    Just speaking out loud here, not from experience. For reference where I work we use SVN for all of our projects, with the exception of kernel/u-boot work which is kept in git and patches stored in SVN.   I am a programmer, my wife is a graphic designer. I love revision control. She hates it.   What about having a system that autonomously monitors the live drop box folder. As files are changed / added / removed it keeps a secondary git repo ( separate from your code repo ) up to date. With the right tools on the server you can download a snapshot of all assets a any point in time without having to clone a terabyte of history, but the history is still ( mostly ) there. You won't get perfect history ( for example if a file is renamed ) and you run the possibility that a file is updated twice before your local copy is synced so you miss the intermediate. Maybe drop box has API's that would give you this information.   --Z
  2. I don't get c++11.

    c++11 to me was largely a quality of life improvement. Some other features that haven't been mentioned:   Non-static data member initialization - Being able to declare the default value of a member variable at declaration ( where it should have been ) instead of some constructor somewhere else. ( My personal favorite ) Delegating / Inheriting constructors - How many times have you had to write an init() because of multiple constructors. constexpr - Kind of like a type safe macro's.   --Z
  3. I had to implement configuration of network interfaces for a remotely managed system. I found shelling to netsh to be the most complete and reliable way to do this. The win32 API is incomplete, hacking the registry is a gambit, and WMI has quirks ( for example, if an interface did not have a cable plugged in WMI could not change its settings ).   --Z
  4. OpenGL Rendering text

    I've based my font rendering on this: http://code.google.com/p/freetype-gl/   --Z
  5. Are you just trying to read from the device raw? You need to read events:   Quick hack cut+paste from another project:         int fd = ::open( "/dev/input/event0", O_RDONLY | O_CLOEXEC );         if( -1 == fd )             return false;         char name[ 32 ];         if( -1 == ioctl( fd, EVIOCGNAME( sizeof( name )), name ))             return false;                  // Grab input         if( -1 == ioctl( fd, EVIOCGRAB, (void*)1 ))         {             printf( "Failed to grab input %s: (%i) %m", name, errno );             return false;         } struct input_event ev; memset( &ev, 0, sizeof( ev )); if( -1 == read( m_input, &ev, sizeof( ev )) ) { printf( "read() failed: (%i) %m", errno ); return; } if( ev.type != EV_KEY ) return; if( ev.value != 0 ) return; if( ev.code == KEY_F11 ) next_channel(); else if( ev.code == KEY_F12 ) display().show_osd( !display().osd_visible ); You will want to enable non blocking, then handle the EAGAIN when the read fails.   -Z
  6. How to get adress from adapters?

    WMI and the IPHLPAPI are the only two native API methods for retrieving IP information. WMI is hit or miss on a good day, so I would avoid it. It's also COM, so unless you are a COM guru, or you are working in a managed language, that's another reason to avoid it. To query a list of adapters on the local system I use GetAdaptersAddresses(). This function will return a linked list of IP_ADAPTER_ADDRESSES structures. ( See the MSDN page about allocating the buffer for these structures ). The IP_ADAPTER_ADDRESSES structure has a member named friendlyname that is the name you see when you bring up network connections. This is the only function call / structure I have encountered that contains this information. The adaptername is the GUID identifying the adapter on the system. The rest of the members are somewhat self explanatory, and explained decently well on MSDN. Even with the IPHLPAPI there are some other caveats that I have encountered dealing with network interfaces: 1) If the interface is disabled, then it will not be included in the list. 2) If the interface is disconnected ( cable unplugged ) then it will not return any IP information even if it is statically configured. To get the current static configuration when the adapter is disconnected, use the registry. I've actually found that the registry is the most reliable source of information for getting an adapters configuration. 3) If you need netmask, then you need to go to a different API ( or get it from the registry ). For some reason netmask was omitted from GetAdapterAddresses() / IP_ADAPTER_ADDRESSES. 4) If you need to change the IP configuration of an adapter, there is no native API. Use CreateProcess and netsh.exe. WMI can configure an interface, but cannot configure an interface that is disconnected. To get the media state, I use GetIfEntry(). --Z
  7. After posting this I struck on the answer. The template types for functions can be inferred, but not those for classes, hence the nesting used by shared_ptr. --Z
  8. I've been looking at the std::shared_ptr and boost::shared_ptr implementations recently trying to learn more advanced template programming and I've encountered a construct that I don't understand, and don't know what it is called to effectively search for it either. For example, here is a simplified snippet from std::shared_ptr [code] template< class _Ty > class shared_ptr { public: template< class _Ux, class _Dx > shared_ptr( _Ux *p, _Dx dt ); }; [/code] When I create a shared pointer I can specify a deletor, for example: [code]std::shared_ptr< char > p( malloc( 100 ), free );[/code] The only template type I provide is that of the underlying pointer, in this case char, however the constructor has a template associated with it that seems to get inferred instead of implicitly being defined like the template for the whole class. At a minimum what is this construct called so I can at least better search for it. Searching for nested templates predominately gives me results on polymorphism with templates. Can anyone explain to me how the secondary types _Ux and _Dx are inferred? Thanks, --Z
  9. On a win32 platform your two best options are WinINET or libcurl. Personally I prefer libcurl. As for P2P: It was popular for patch distribution several years back ( blizzard pioneered it, many copied ) as it reduced load on your patch distribution servers. However with the surge of CDN's ( Cntent Delivery Networks ) like Akamai, CDNetworks, LimeLight, etc. it is simpler / cheaper to use them. They all support HTTP. ( Even Blizzard has moved to a CDN and it is vastly superior to P2P ). --Z
  10. Don't know how to wrap classes to Squirrel

    I've never used sqrat, and I admit that I haven't touched my project that uses squirrel in a long time ( so my memory is rusty ). But here are some snippets of how I expose classes to squirrel: [code] void Scripting::createClass( const char *name, const char *inst, void *userptr ) { try { sq_pushroottable( m_State ); sq_pushstring( m_State, name, -1 ); if ( SQ_OK != sq_get( m_State, -2 )) throw Core::exception( "sq_get() failed" ); sq_pushstring( m_State, inst, -1 ); if ( SQ_OK != sq_createinstance( m_State, -2 )) throw Core::exception( "sq_createinstance() failed" ); if ( SQ_OK != sq_setinstanceup( m_State, -1, (SQUserPointer)userptr )) throw Core::exception( "sq_setinstanceup() failed" ); if ( SQ_OK != sq_newslot( m_State, -4, SQFalse )) throw Core::exception( "sq_newslot() failed" ); sq_pop( m_State, 2 ); } catch ( std::exception &e ) { Core::Log::printf( Core::Log::SCRIPTING, Core::Log::ERR, "Scripting::createClass() - %s", e.what() ); throw Core::exception( "Scripting::createClass() - %s", e.what() ); } } [/code] The class has to have already been defined in the VM. This creates an instance of it. The way I am currently using this is for global singleton like objects. For example I have a display class that has functions for manipulating the display. I create an instance of it so that is already available to the VM. --Z
  11. Quote:Original post by Litz Understood everything, thank you very much. What I was doing was basically have a database server (made by me) connect to a database (using MySQL), and saving whatever was important, so I ended up doing everything there. I'll keep that server for the sole purpose of querying the database and sending the results back to the Login/World server now, and keep the actual logic on those servers. You shouldn't have a service that your services connect to for the sole purpose of being an intermediary to the database. Just have each service ( be it login, world server, NPC AI server, etc. ) connect directly to the database using the native database api. Database engine vendors ( i.e. MySQL, MSSQL, Oracle, etc. ) spend millions of man hours working on caching algorithms, data integrity, query optimizations, etc. Don't defeat that work by trying to write your own cache in front of the database. Odds are pretty good that whatever you write will not be as good as what the database engine itself can do. Having your services connect to the database directly is also less work in the long run. Instead of having to write code in the service, that sends a special command to the db front end, which has special code to convert this command into SQL, which then gets the result and has to handle buffering it back to the caller, which then has to interpret and use it; you just issue the SQL command directly from the requesting service and handle the result. This also simplifies debugging as you have simplified the system, making it much easier to trace. You've also made it easier to maintain since you no longer have to change two services to make one change. The web analogy of your design is a web page that makes a request to another web page on the same host to get data from the database. On a side note: Since this is a learning exercise you might want to look into virtualization. With virtualization you can use one piece of hardware to run multiple separate servers. There is no reason your services can't all run on the same host, I just bring this up as a learning tool to make it feel like you have a server cluster. To get your feet wet Virtualbox is quite good. If you have a dedicated system you can use, VMWare ESXi 4.x is also quite good. If you don't have spare hardware, but still want server style virtualization VMWare Server is also pretty good. All of these are free. I plug this as I do this at work to simulate systems ( at low load ) as it is just as easy / cheaper than having physical hardware. --Z
  12. About the behaving of the servers

    Quote:Original post by Navychan 1) supose fd is a file descriptor to a socket struct epoll_event ev; int efd = epoll_create(5); ev.events = EPOLLIN | EPOLLRDHUP | EPOLLERR; ev.data.fd = fd; epoll_ctl(efd, EPOLL_CTL_ADD, fd, ev); once I have attached the fd to the epoll, can I: close(fd); and expect it to work properly? what I mean is... if I can't close the entrie on the channel table I'll have a limit of 32 clients per thread (I'd say I don't want this by any means but... let's just say I don't think this is the proper way to go...) No, you cannot close the descriptor. Where do you get this number of 32 from? epoll can scale up to many thousands of descriptors. Quote:Original post by Navychan 2) assuming everything goes on fine... I come back to the original doubt, if I have the clients all hidden in some place on the kernel, how would I iterate over them to send each of the messages I have to send? or is the client who should keep polling? :S Many thanks and sorry for the large post along with the more than possible english errors. You will still need to maintain a list of active connections ( and there associated persistent state in your game world ). You cannot just hand off the descriptor and forget about it. The snazzy thing about epoll is that you can provide a user pointer in the epoll_event struct. So you can stuff in lets say a pointer to a structure to get immediate access to that clients state. Alternatively you can search your client list for the fd that epoll triggered on. --Z
  13. Worms server logic?

    Klapaucius is right. Get your game to market, and when you have achieved success and cheating becomes an issue ( cheaters target popular games, it isn't worth the effort for low pop games ), then fix it. The cheating problem you will encounter with a worms type game is auto-aimers. A cheat program that reads out player position and wind speed to calculate the perfect angle for the weapons used. No client or server side logic can detect this. This was the big problem Gunbound had to resolve. Their solution ( last I checked, which was a long time ago ) was to use some very deep almost root-kit technology to prevent third party apps from accessing the Gunbound memory space. I don't know how successful they were. --Z
  14. These problems have been sort of solved in professional games, just no one seems to write about them. World of Warcraft has had it's arena match making system modified multiple times. It operates very similarly to what you are after ( matching teams based on ratings ). They may not publish is though because they don't want players to know the inner workings so they can't game the system. Another possibility to consider that hasn't been brought up is the idea of applying a handicap to the better player ( or a buff to the less skilled player ) in an attempt to even the match through altered game mechanics. This may not apply to your game mechanics, and you would want to be upfront about it in the match making. --Z
  15. "It's lonely at the top." - Sorry, couldn't resist. I don't know of any articles on match making with an unevenly distributed set, just a thought I had while reading the post that may inspire you to a solution. An idea would be to use time in the queue to decay a player's actual rating to a virtual rating. The longer they are in the queue the more likely they will be matched up with whomever is the best player below them. virtual ratings would be compared to actual ratings when determining a match. At the end of the match the participants ratings are adjusted by the amount of time based decay that occurred to make the match occur. Meaning that player A with a rating of 2655, who is matched up with player B whose rating is 2044 would only gain maybe a single point for a win, while player B would only lose a single point. Conversely, if player A loses to Player B, then Player A loses the same amount of points as if they had lost a match at there level, and player B gains points equal to them having won a match at there level. The upside of this is that top ranked players would eventually be queued against someone. The downside is that it would be for little gain. Something else you may want to take into consideration when match making is the time other players have been in the queue. Simply generating a set of matches based on the threshold, then choosing the player in that set with the longest queue time. --Z