Archive for the ‘Game Development’ Category

Early impressions of Unity

Thursday, September 29th, 2016

Unity  5.4.1 initial pros and cons, from someone learning it

Pros (in order of importance):
1. The documentation is pretty good, but the forums are awesome. With so many users, nearly any question you have someone else already had. The forum users are active and helpful, and will often paste the code answer directly.
2. Because the basics are easy, it’s easy to debug basic errors. For example, drawing rays so you can view the normals on a mesh, rendering to a texture, or throwing debug buttons in the editor.
3. The price is amazingly cheap for a game engine of the quality. Back in the old days game engines with a complete toolset were hundreds of thousands to millions of dollars. You don’t get source at the cheaper levels, but so far I haven’t felt the need for it.
4. The asset store is great, which a wide range of tools, and extremely cheapl. It’s programmer time for free to (usually) under $100.
5. Many major companies have official add-ins for Unity, so you aren’t too limited in major 3rd party support.
6. Unity is relatively friendly to beginners. For example, if you delete all lights from the scene you aren’t just left with a black screen. You are helped through common mistakes such as using material instead of sharedMaterial.
7. Direct support of native file formats for major artist tools is great. I think in practice you will want to export for faster speeds, but during prototyping it’s very convenient.
8. Despite the price, it is possible to make high-end graphics for high-end games.
9. Supports a huge number of platforms.

Cons (in order of importance):
1. GameObject is the basis of everything in your scene, but GameObjects are slow. Because all subcomponents are part of GameObject, this leads to conflicting requirements. For example, if you want to render a lot of terrain it’s better to break things up for rendering but for Physics it’s better to use fewer large colliders.
2. The standard shader is conditionally compiled such that it is optimized for the target platform (which is great) but you can’t extend it without losing that, especially important for mobile.
3. Not sure if Unity is still using RakNet, but many superior features of RakNet were left out. For example: automatic peer to peer host migration (no handshaking necessary), UPNP (which removes the need to pay Unity or limit concurrent players), and hosting your own servers without a source license.
4. The Visual Studio integration is buggy.
5. Unity uses a left handed coordinate system, which doesn’t match Max or Maya

Except for the GameObject performance, the cons are minor compared to the pros. Overall Unity is a good choice for game development.

New congestion control thanks to UDT

Tuesday, August 18th, 2009

A few years ago, a user in the forum stated that UDT had much higher throughput than RakNet for LAN transfers. I took a look at it and it was made by a couple of research scientists for the purpose of being faster than TCP. While they published details of their work, the documentation is extremely technical and academic. Anyway, I said at the time that RakNet was designed with different goals, and if all they wanted was high speed LAN transfer to use UDT instead.

Since that time, I had ongoing problems with congestion control. Every 2-6 months I’d try a different approach with incremental improvements. But with the wide range of scenarios under which RakNet is used, there was always a new scenario where it didn’t work. So I basically gave up, and turned to UDT for help.

My first approach was to directly integrate UDT into RakNet. I spent about a week removing all exceptions from the UDT source, changing to the RakNet memory allocator, and integrating RakNet to use UDT for sends and receives through RakNet’s own sockets. I had it working, but had problems where UDT didn’t connect as fast as RakNet. UDT also didn’t support priority levels or different sending types other than RELIABLE_ORDERED. I wasn’t happy about having another UDP library integrated into my core product just for one feature (congestion control). In the end, I released this an optional define flag. It’s present in version 3.62 though I left it disabled by default.

At random, I saw an advertisement by one of the authors of UDT, Yunhong Gu, for paid contracting. Rather than have him code a solution, I had him write a technical design document on how the UDT congestion control was implemented, so I could implement it myself.

The result of my implementation

Using DevPartner performance analysis I eliminated the top 20% CPU utilization from RakNet. I also reduced the bandwidth overhead, even though more information is sent. In the end, I raised the file transfer rate on localhost from 2 to over 20 megabytes per second (I’ve seen it go as high as 40 on another computer). And the transfer rate to my remote server went up by 50%.

I’m pretty happy with the end-result. This is probably the most significant improvement to RakNet I’ve made since it was developed. I’ll be releasing this as version 3.7 in the very near future.

One of those rare cases where a linked list is the best data structure

Thursday, August 6th, 2009

I have a B+ tree containing pointers, sorted by key. I had a queue which mirrored that tree, but was ordered by a fixed-interval timestamp (from most recent to least recent). I recently encountered a situation where I was able to look up the pointer by the key in the B+ tree, but didn’t know its index into the queue. Since the queue could be tens of thousands of elements long, and the same op. had to be repeated many times, it was too slow to stick with. So I changed to a linked list. That way I could remove from the middle of the queue and readd at the head of the queue without scanning the queue for its index.

Function calls as data

Saturday, July 25th, 2009

I’ve been using a function object design pattern for my Lobby system and it’s working well enough that I wanted to post about it.

The concept is very simple. Encapsulate the input and output parameters to a function, and the function call itself, in an object. This lets you manipulate a function call the same way you do objects.

Some useful things you can then do:

  1. Serialize them over the network
  2. Save them to disk
  3. Put them in a queue, for a test execution path
  4. Save them to call later
  5. Move the inputs and outputs around between threads
  6. Log what runs
  7. Perform operations on a set of function objects via the base class
  8. Give the user more functions by giving them more function objects from a class factory, making the system easy to extend.

So the lobby system exposes a large set of function objects. The user gets one from the class factory, with an identifier for what function to perform. The input parameters are filled in. They are serialized, processed remotely, and sent back. The user has all the contextual information because the input parameters are sent back as well as the output parameters. And a cool thing about this is the memory for function call lives on the internet. From the client’s point of view it is stateless. The client doesn’t have to track what is running.

It’s also useful for asynchronous operations.

In my case, rather than having a function pointer, the functor’s operation is in the functor itself (e.g. DoWork()). The needed parameters are passed to DoWork(), and operate on the database.

Thoughts on contracting

Saturday, May 9th, 2009

It’s interesting, even to myself, how contracting has changed my perceptions of labor over the last few years.

When I started contracting, I didn’t act any differently from the employee I was used to being the prior years of my career. I generally came in the same hours, spoke to the same people, attended the same meetings, and did similar tasks. However, there was a seed in the back of my mind that I was now working for myself and the company was a customer. A crucial difference, now being able to say “Why would I go to the company party? I don’t work here.” It’s like when you meet your boss for the first time in the interview, and he’s just a normal guy like any other. Eventually that feeling turns to “my boss” but if you’re a contractor it’s “my customer” and he’s still just a normal guy.

It’s become a strange concept to me that a company can control your comings and going. I know it happens because I see it happen to others, and I remember it happening to me when I was an employee. I used to have boring days where I would sit there and watch the clock until I could go home. That thought now evokes images of outrage, and slavery. How can someone else tell you, a human being, where you can and can’t go, or when you can do it? I used to complain that I’d have to sit there if I had nothing to do. Now, it’s my own time. Once my customer is happy with my progress, I go do something else. Sometimes work for another customer. Sometimes I keep working for them, but at my own office.

There is no longer a line between work and home. My job for the client is to ensure they are happy with the services I provide so they continue to be a customer. I don’t complain about working nights or weekends if I need to, because all the time is my own to begin with. Time is not relevant, only the assigned work is.

Similarly, there’s no issue of doing the minimum work to get by, because I’m not working for someone else directly. I’m providing a customer with a service, and of course when running my own company I will do the best job possible.

I could never go back to being an employee. The feeling of freedom working for yourself is like the feeling of being alive.

Here’s some random tips to help out other contractors or potential contractors.

1. The employer will act outraged, shocked, and/or feign ignorance of the various costs and taxes when they hear your price. But it’s just a negotiating tactic to pay you less. Knowing the facts, showing you know them, and not backing down directly equates to more money
http://www.rakkar.org/ContractPayCalculator.html

2. Not all employers understand the laws or differences between contractors and employees. When I first started contracting I thought of the differences in terms of the law, but now I just think of the differences in what I am willing to work for a customer.

For example, if the company insists that you be there certain hours although you have nothing to do that day, you can say “My monthly fee is for roughly a month of tasks. While I don’t charge less for months where I have less to do, neither do I charge more when I have more to do. I’m happy to stay, but I’ll be billing hourly and this will cost you more in the long run, especially during crunch time.”

3. If helps if you make so much money or are in so much demand that you don’t need a particular customer or job, and are therefore able to drive harder bargains and set your own terms. Having your own business makes much more money than being an employee, and after a few years you tend to reach this point.

4. Flying around the country invokes a very real time and cost to you, that is hidden to the customer. A two hour flight takes three or four hours each way when you count check-in and the drive to the airport. At the end of the day you’re probably not going to be doing much other than watching TV in a hotel. And you get nothing for the unpleasantness of sitting in an airplane.

Jobs where I didn’t charge for this time made me unhappy in retrospect, four days of effort for two days of pay. However, jobs where I did charge (a discounted rate) for this time made the customer unhappy, especially as I didn’t charge for that time previously. I can see their viewpoint – you are charging more than they make themselves just to sit on a plane and do nothing useful for them. The approach I’ve taken now is to just bill more for short-term contracts. Although, even at the rates I charge ($125 an hour) it still isn’t worth my time or effort financially. I think of it as a necessary support effort I provide for licensing fees I’ve already made, rather than a source of income.

Irrlicht demo converted to multiplayer demo

Saturday, April 25th, 2009

I took the demo for the game engine Irrlicht and added multiplayer to it in two days.

Download

Technical details

Screenshot

I have to say again that Irrlicht is a great engine. Very easy to use, very well documented. I had to go to the source a few times but it was nothing major.

Middleware X 7 = Uberengine

Wednesday, April 22nd, 2009

I was thinking lately what a good market middleware is

  • Write once, sell many times
  • Focusing on a specialty lets you beat out companies that do that one thing incidentally
  • Even as an individual with no marketing, you can outperform large companies that spend 100x what you do

And thinking to take that to the next step, with a game engine. I’ve noticed that game engines get many times the attention of individual libraries, much more so than the sum of their components. Imagine a game engine where each component is a specialized best-of-class library. RakNet times 7, the other 6 being graphics, physics, audio, AI, UI, and tools. If I knew 6 other developers or small companies that had the same quality as RakNet, at a similar price, it would be a great venture to join forces and make an engine as the integrated sum of those libraries. Such an engine would dominate the market immediately in terms of quality, because no existing monolithic engine, no matter how good, could beat a specialized company that focuses on that a single aspect. If you were to take all these specialized companies together then, all other engines would be fail because none of them could compete in any area.

It’s sort of like how you can take any default Windows application and find a better substitute on the net. It’s not that Microsoft did a bad job, but that their focus was on an operating system. Specialized companies turn around, find a niche market for that application, and beat Microsoft because that is their core focus. If you’re not going to do a way better job then there’s no point in entering the market.

If these libraries could be integrated seamlessly, with the full feature set for each library exposed, it would like astounding.

Irrlicht is a great engine

Wednesday, April 22nd, 2009

I’m revisiting Irrlicht to add multiplayer to one of their demos. It’s a fantastically easy to use engine that is well-written and well-documented. A few years ago I didn’t use it for Galactic Melee because of lack of tool integration support. Hopefully it’s better on that now, although Ogre didn’t turn out to be that well-integrated into tools either in hindsight.

Some people have to learn the hard way

Sunday, April 19th, 2009

I’ve been working with the owner of a new engine lately. It’s an interesting scenario: He paid a programmer to write an engine for him apparently on a contract basis. The programmer did so and went on his way. Then he then hired some artists to make content. That was done. He is now trying to sell the engine, and I took a look at it to see about integrating RakNet.

A concise summary is “Promising but won’t save you time”. Promising in that there are many libraries to do many different things, and with a few script calls you can get a lot done. Won’t save you time in that it is undocumented, complex, heavily specialized for a particular type of game, and uses macros and cast-from-void-pointer hacks to avoid having to write interfaces.

I read a similar complaint in the forums

User: “How do we do this?”
Owner: “Look at the source”
User: “The library is closed source. It is impossible to do anything”
Owner: “It is possible, you just have to figure it out.”

The reason for that is the owner is not a programmer, and doesn’t want to pay a programmer for general forum support.

So I brought this to his attention

Me: “If you want to succeed, you need to document your stuff. I can’t figure out how to do anything. Other people who buy it aren’t going to be able to use it, and will be pissed off.”
Owner: “The programmer said experienced users don’t need documentation. They just look at the source.”
Me: “It is closed source. The programmer is saying that because documentation is not fun to write.”
Owner: “I don’t want to pay for documentation. If we’re successful, it’ll have documentation at some point.”

Hopefully things come through for them, but I doubt it will.

Multiple typed dynamic array

Thursday, March 26th, 2009

I wrote DS_Multilist.h. It’s an unordered list, stack, queue, and ordered list all in one. Since the interface is the same for all 4, it’s easy to change what type of data structure you are using to tweak performance. Relatively full featured, with a sort function and fast lookups into sorted lists.

Multilist