Category: Uncategorized

I simply hated this one. The dreary level design was complemented by excessive numbers of guards that were no fun to subdue. I played it once and have never been back. I won’t even do the bookkeeper, because he’s there. The thing I didn’t like was the big reveal at the end of Colorado. Surprise: It’s his clone/brother/best friend trope who somehow magically took a different path and is all knowing, all seeing, and able to orchestrate the whole shebang. If it doesn’t turn out that there’s someone behind him I’ll be greatly disappointed. To be fair, this level of writing (B Movie Quality) is Oscar worthy in a game.

The dialogue and plot, for a game, is absolutely off the charts. Nevertheless, it would have been nice for them not to go “World Conspiracy”, it’s hard to find anywhere to go after that, except space aliens. Come to think of it, Agent 47, cryogenically frozen for hundreds of years, only to wake up in a highly technical future with space aliens? Fuck – I should write this down.

Run this command in the same folder you saved setup-x86_64.exe to:

.\setup-x86_64.exe -q -P wget -P gcc-g++ -P make -P diffutils -P libmpfr-devel -P libgmp-devel -P libmpc-devel -P cmake -P cmake-gui -P gdb -P git -P libboost-devel -P python3 -P chere -P gnu-free-fonts -P xinit

I finally decided to sit down and learn game development. From my research there is only one way to do it, and that is SDL. If it’s good enough for Valve and Steam, it’s good enough for me. As it turns out, it’s surprisingly easy to get up and running with SDL. There are plenty of tutorials about the basic SDL game setup, so I won’t repeat the ubiquitous info and go straight to some basic problems of making a game that no one really seems to discuss.

There are two main problems when designing a game:

  1. How do I save and restore game state?
  2. How do I make my game configurable?

C is a great language for speed and algorithms, but it is really shitty when you want to handle data. Games are both algorithm and data intensive. So for half the game development, C rocks. But for the other half, it’s a slog.

Saving and restoring game state means populating a structure in your C code with values from a human editable, dynamically loaded file. Things like the x,y or even z coordinates of the player in game space, their health, equipped weapon, inventory items and so on.



One solution for solving this problem is to use some kind of config file format like INI, or XML. INI is a good choice for very simple games, and it’s dead simple to write an INI parser in C. The other common option is XML, which means something like libXML, which means I’d rather have my eyes gouged out with rusty spoons. On top of generally hating XML, interfacing from C with XML is a nightmare and 1/2.

There is a third option though, which can be better or worse: Embedded Scripting Language.

Using an embedded scripting language to setup game state is pretty standard practice, most big games use either Lua, or Python.

I’ve embedded Lua in a C application before, and I never want to do it again. I’ve also embedded Python, and it’s better. Also, I like Python a lot, so it would have been my fallback choice here. I also like Lua, a lot, but embedding it is not as fun as you’d think. I am overstating the problem of embedding Lua, it’s not that hard.

There are of course other options, one of them will probably scare you to death. Don’t run, you’ll only die tired.

In the case of Lua and Python, and libXML and just about any other scripting language, that’s yet another DLL you have to distribute.

When first trying to solve this problem I found JSMN, which is a self-contained dependency free JSON parser. Since I love JSON as a format for storing info I plugged it in and tried it out. It’s worth considering, but it’s a bit like embedding Lua(actually a bit worse). There are no convenience methods for working with the data, and you’ll have to build the worlds biggest State Machine to do anything with it. I dumped Jasmine pretty quick when I found TinyScheme.

I can hear your footsteps already on your way to the door. But hear me out. Scheme is actually the perfect solution because XML is just Retarded Lisp without any functionality. TinyScheme, which is a dialect of LISP has all the power of representing Hierarchical Data, plus if you’re hardcore, you can mix in some programming logic too.

Since TinyScheme is small, fast, and has 0 dependencies, it really appealed to me. The best thing about it, it’s the easiest embed of a language I’ve ever done.

Basically you download TinyScheme from SourceForge and you plop the files into your src directory, add them to your project and boom, you’re ready to go. You’ll need to make a few changes to the header file scheme.h

#define USE_DL 1
#if USE_DL
#define USE_INTERFACE 1
#endif

After that, I made a small addition to scheme.c around 2288 that allows for the writing of script errors to an error log.

/* ========== Evaluation Cycle ========== */
#include stdio.h
#include stdarg.h
#include stdlib.h
void scheme_log_info(char *msg, ...)
{
    FILE* lf = fopen("scheme_log.txt","a");
    va_list argp;

    va_start(argp, msg);
    vfprintf(lf, msg, argp);

    va_end(argp);

    fprintf(lf, "\n");
    fclose(lf);
}
static pointer _Error_1(scheme *sc, const char *s, pointer a) {
...

Then at line 2330, I’ve added scheme_log_info(str); which effectively appends errors to a text file, which helps when debugging, especially if your aren’t familiar with Scheme. The errors are largely unhelpful, but at least you get a line number.

REMEMBER: You want to include scheme-private.h, not scheme.h

Basic Theory of Embedding Scripting Languages

The basic idea of an embedded scripting language is that you have an init function that creates a context or environment which is basically a little sandbox scripting world into which you will load strings of that scripting language and they will be executed.

Some scripting languages allow you to evaluate code and receive a result, and others focus more on executing code.

With a fresh vanilla context you can’t do much, so you need to register some callback methods into the environment. These methods, or functions, are usually just pointers to your C functions which usually have to match the recommended signature expected by the scripting language. Almost universally the signature is pointer_type myFunc(lang* context, pointer_type args).

The pointer_type is usually defined by the language, and some might require that the callback be void. When a scripting language requires a pointer_type returned it usually means it’s going to actually use the return value, possibly in another callback call.

Once your callback is called you will need to unwrap the pointer_type to a sensible datatype for C, like int, char* and so on, and most scripting languages that support embedding have a bunch of helper functions to get at useful datatypes.

With these things understood and in place, initializing the context, and then providing it code to execute, and callbacks that make the execution worthwhile, and implementing the unwrapping, you’re halfway there.

Thankfully, for our purposes we only need 1 way communication. We just want to get things into C from the scripting environment, not the other way around. At least not yet.

Why Scheme as good as XML

In this particular situation Scheme is as good as XML because it’s easy to represent data structures as S-Expressions. Here is an example of my Player Object, including it’s sprite sheet and clipping info in Scheme:

(set-player-attributes 
   'x 640.000000 
   'y 400.000000 
   'speed 4.000000 
   'height 0 
   'width 0 
   'health 0 
   'current_frame 2 
   'total_frames 7 
   'base_frame 0 
   'idle_frame 0 
   'idle_total_frames 7 
   'walking_frame 8 
   'walking_total_frames 5 
   'action1_frame 0 
   'action1_total_frames 0 
   'action2_frame 0 
   'action2_total_frames 0 
   'action3_frame 0 
   'action3_total_frames 0 
   'action4_frame 0 
   'action4_total_frames 0 
   'sprite_sheet "assets/images/player.bmp" 
)
(set-player-sprite-clip 0 'x 0 'y 0 'w 32 'h 100)
(set-player-sprite-clip 1 'x 0 'y 0 'w 32 'h 100)
(set-player-sprite-clip 2 'x 0 'y 0 'w 32 'h 100)
(set-player-sprite-clip 3 'x 0 'y 0 'w 32 'h 100)
(set-player-sprite-clip 4 'x 0 'y 0 'w 32 'h 100)
(set-player-sprite-clip 5 'x 0 'y 0 'w 32 'h 100)
(set-player-sprite-clip 6 'x 0 'y 0 'w 32 'h 100)
(set-player-sprite-clip 7 'x 0 'y 0 'w 32 'h 100)
(set-player-sprite-clip 8 'x 244 'y 0 'w 41 'h 100)
(set-player-sprite-clip 9 'x 285 'y 0 'w 30 'h 100)
(set-player-sprite-clip 10 'x 315 'y 0 'w 29 'h 100)
(set-player-sprite-clip 11 'x 344 'y 0 'w 36 'h 100)
(set-player-sprite-clip 12 'x 382 'y 0 'w 32 'h 100)
(set-player-sprite-clip 13 'x 414 'y 0 'w 32 'h 100)
(set-player-sprite-clip 14 'x 0 'y 0 'w 0 'h 0)
(set-player-sprite-clip 15 'x 0 'y 0 'w 0 'h 0)
(set-player-sprite-clip 16 'x 0 'y 0 'w 0 'h 0)
(set-player-sprite-clip 17 'x 0 'y 0 'w 0 'h 0)
(set-player-sprite-clip 18 'x 0 'y 0 'w 0 'h 0)
(set-player-sprite-clip 19 'x 0 'y 0 'w 0 'h 0)
(set-player-sprite-clip 20 'x 0 'y 0 'w 0 'h 0)
(set-player-sprite-clip 21 'x 0 'y 0 'w 0 'h 0)
(set-player-sprite-clip 22 'x 0 'y 0 'w 0 'h 0)
(set-player-sprite-clip 23 'x 0 'y 0 'w 0 'h 0)
(set-player-sprite-clip 24 'x 0 'y 0 'w 0 'h 0)
(set-player-sprite-clip 25 'x 0 'y 0 'w 0 'h 0)
(set-player-sprite-clip 26 'x 0 'y 0 'w 0 'h 0)
(set-player-sprite-clip 27 'x 0 'y 0 'w 0 'h 0)
(set-player-sprite-clip 28 'x 0 'y 0 'w 0 'h 0)
(set-player-sprite-clip 29 'x 0 'y 0 'w 0 'h 0)

This isn’t the only way to do it, it could be even fancier, I but I elected for a direct Scriptable style, where callbacks are used to set data. The other way to do it would be to quote the whole S-Expression and then navigate it as a true List. If I did that, we’d lose the simplicity angle for people who aren’t into Lisp/Scheme. With the above, you don’t even have to know it’s LISP, it’s Just a Text Format. Don’t ask why things are the way they are, you just do it and it works.

Here’s how it might look as an XML file:

<player>
   <attributes>
      <x>640.000000</x>
      <y>400.000000</y>
      <speed>4.000000</speed>
      <height>0</height>
      ...
   </attributes>
   <sprites>
      <clip>
        <index>0</index>
        <x>0</x>
        <y>0</y>
        <w>32</w>
        <h>100</h>
      </clip>
      ...
   </sprites>
<player>

I didn’t write out the full example, because it’s verbose…yeah, another reason I don’t like XML.

With the Scheme version, I made it so that each individual clip is also scriptable, so extensions and community content can alter it, including creating entirely different sprite sheets and animations.

This also means that I can reuse this code in any game to make players and even enemies.

The core idea behind all programming is: Never Repeat Yourself. Write it once, use it many times. We are always building frameworks for our software.

The C Side

You should know by now the basic structure of a Game.

BasicGameDesign

Our general idea with a game is to get from main to the GameLoop as quickly as possible, and simply rendering elements to the screen.

Our GameLoop function is a generalized recursive (or while loop if you must) function that gets called indefinitely and divies out the game logic duties for our program.

The game loop performs these tasks:

  1. Should I continue? If not, Quit(freeing resources) and return (therefore exit program)
  2. Call the function that calculates the current frame of animation for all game objects (including the player)
  3. Loop over all game objects and draw them to the screen
  4. Should I cap the Frame Rate? If so, Delay

Here is an example of an actual GameLoop I am using in a prototype side-scroller game with SDL 1.2

BasicGameLoop

 

Now you need a place to store State. State is universally important to a game, and you need a couple of structures in your program. The most important one is the Generalized GameObject:

GameObject

This big struct has everything you need to represent some GameObject in the game.

The sprites member of the struct is where we keep all of the Clips that get created with the Scheme call (set-player-sprite-clip 0 'x 0 'y 0 'w 32 'h 100). The first argument 0 is the index of the array, and the rest are the named 2by2 pairs of attributes.

The sGameObject struct also has information about frames. current_frame and total_frames and base_frame deal with the currently running animation.

idle_frame, walking_frame and action1-4_frame deal with different generic animations, in this case aside from walking and idle, I have these 4 generic actions that could be shooting different types of guns, or punching, throwing, high and low kick etc. Compairing base_frame with idle_frame will tell you that the GameObject is idle, if comparing base_frame with action3_frame will tell you the GameObject is performing that action and so on.

Since this game is still in the prototype phase, this structure could evolve over time.

The most important member is the id, which lets you know what kind of GameObject it is. An id of 0 could mean player, and id of 1 a certain type of enemy, etc.

Notice sGameObject is not typedef’d. Don’t abuse typedef. If you don’t actually need it, don’t use it.

A note on GameObject

Everything in your game is a GameObject, or nearly everything. The player, all the enemies, all the bullets, ammo refils, and anything that can be interacted with, like a door or a switch. To reach the end of a level, you can place a blank GameObject for the player to collide with that ends the game.

 

EliteDangerous_MostCommonScreen1

 

Elite: Dangerous is an ambitious game, and on the whole is very well done. Though I would say it has been and continues to be plagued with a number of unfortunate gameplay killing problems, I expect that most of them will be taken care of post-haste.

Games generally have two major problems, both are the game designer/programmer/producers fault:

Buggy Client/Server

The first kind of problem is the buggy client or server, but this is a fault which we can’t really hold against them, because it’s not like there is some cadre of developers twisting their mustaches and laughing about how often the client or server goes down or disconnects. It’s irritating, but generally the pleasure gained playing the game while it’s working can offset this problem. There is also the issue of being an early adopter of a game, the sooner you get in, the more money/power/respect you’ll build up in the game so coping with the growing pains of the client and server as well as the game has its benefits.

Shitty Gameplay

The other problem a game can have is shitty gameplay, which is a rather broad category which spans from irritating mechanics all the way up to “you’ve got to be fucking kidding me.” While Elite:Dangerous seems to have minimized any serious fun killers, there are a few mechanics which just piss you off to no end.

When you couple these issues with the fact that if rand(10) < 5, the server randomly disconnects, or crashes, especially while in SuperCruise, HyperDrive, or when flying too close to a planet, the one thing that is most irritating about Elite:Dangerous is the time it takes to do things. I am not talking about travel time, that’s already bad enough, I am talking about getting shit done, and it seems to take for fucking ever. The game has a loading screen, and each station has a loading screen. What the fuck is it loading?




I hope it’s not actually downloading data when it shows that loading screan, because that would be really stupid design, I haven’t done anything yet, don’t load anything unecessary, and it would probably be better just to show the station menu so I can refuel/reload, because you have to fucking do that constantly.

I get that reloading/refueling is something you have to do on a regular basis to make it seem more real, but actually it just cuts into the fun, especially when bounty hunting, the fact you have to stop every hour when you are on a roll at a good spawn to pick up more ammo really starts to get on your tits, especially with the Supercruise -> Crash -> Could not connect to matchmaking server x 5 cycle. Once you manage to reconnect, and approach a station, get ready for some kind of weird time dialation, because the minute you approach a large body(planet, star, space junk) Gravity(TM) kicks in, slows your ship down to be slightly faster than a retarded spastic turtle, and then taunts you with a ETA timer that’s off by a factor of 20. All in all, in the best case scenario refueling and rearming takes up to 15 minutes seriously cutting into my playing time. Once you get to the station, you have to land, that’s fine, and the mechanics for that are smooth and even engaging, once you land you have to sit and wait through an unnecessary hangar entrance animation, then when you load the starport services menu, what’s that, a bird, a plane? No, it’s another fucking Loading Menu. Good god, after a couple of hours of this shit you really want to gouge your own eyes out with a rusted spoon.

I want to officially change the name of the game to Elite:Dangerou – Mostly Loading.

Bounty Hunter – AKA Police Stooge

Bounty Hunting in ANY game, ever, has always been a farce of a mechanic, it’s usually just there for the people who can’t be arsed to grind Trade, or Mining, or Exploration. Bounty Hunting in Elite:Dangerous is a grind, with a lather rinse repeat formula. You, and whoever else is there all attack one ship at a time, and you all get unfathomably large bounties. The fact that everyone gets a bounty is cool from the player perspective, but it hurts any argument to realism.

I like the Bounty Hunting mechanic in Elite:Dangerous because when you have a weaker ship, you just go in, take a few pot shots at a wanted ship and then fly around in circles while everyone else kills it, yay, Bounty Mooching is AWESOME! Well, it got me into a viper in 1 day. I quite like the Viper as it sounds a bit like muscle car.

The one major downside of Bounty Hunting in Elite:Dangerous is how quickly and easily you get a small bounty on yourself with some moron glides into your line of fire, at which point, no matter how wickedly evil the current target is, the system authorities begin attacking you, even for a measley 600cr. And I didn’t even destroy his fucking ship.

On top of having to refuel, and reload, you have to fly to a different faction station to pay off your 600cr bounty or they will destroy your 1,000,000cr ship. This leads to serious questions about crime and punishment in the game, because apparently accidentally assaulting another ship, not even destroying it, is just as bad as murdering a school bus full of children. Whatever you do, don’t walk on the grass!

Missions and Quests

Don’t expect anything innovative here, it’s still go here shoot this, or go here deliver this, or go there get this and deliver here. It’s the same old theme and variation that you expect in an MMO, or any game perhaps.

Only the Lonely

Of course, me being the social butterfly that I am, I eschewed solo play and went right for Open Play. But Open Play seems like Solo Play because I haven’t met anyone, or talked to anyone else in the game in a week, or ever actually. I am pretty sure there must be some people there, but they aren’t very social and don’t want to chat.

Summary

To many people point out the good things in a game and none of the bad things. I on the other hand start from thinking a game is shit, so that when it isn’t, I will be pleasantly surprised. It turns out that Elite:Dangerous has on many occasions surprised me. You can actually make decent money exploring, so it seems a valid profession, one I would love to pursue, except I am generally afraid of spooling up my Hyperdrive due to the crash frequency. Once that’s fixed up, I do plan to head out to the farthest reaches of space and do a bit of exploring. Never the less, there is a monotonous component to this as well, it’s a grind, it’s always a grind with only games.

Elite:Dangerous is my brand of shitty online game, because it’s also kind of nerdy. Since it’s early yet, there are plenty of opportunities for expansion, so if you want to get in now and start grinding in the hopes that they don’t nerf the fuck out of it, by all means, it’s worth the 39 quid you pay. Fuck, at least it’s better than EVE Online, so I really want to support Frontier so we can give a big “Fuck you” to CCP.

 

 

I’ve been thinking about this problem for awhile, and I have an idea of one of the major factors preventing LISP adoption: EMACS.

Emacs is, well, complete shit. Vim is also shit. They are the awesomest pieces of shit ever. There are people who love EMACS, and people who love Vim (I like Vim actually), but everyone today uses a real IDE, like Netbeans (I hate it) or at least SublimeTEXT(I love it).

The truth is, you can use something like SublimeTEXT with SublimeREPL plugin and get interactive scripting behavior.

So how is EMACS a barrier? Because when you are a newbie to LISP, and you go looking for information about LISP, the first thing everyone says is: Install EMACS. Most newbies stop reading there. “To hell with that!” they say. EMACS is one of those editors that was a really great idea, 20-30 years ago when computers were way different. The problems that they solved are barely relevant today.

No one uses Macros, no one needs weird navigation with the keyboard. A modern IDE needs clickable tabs, not confusing buffer lists, they need file system tree displays, and project management functions built in, not from some confusing 3rd party lib.

The features an IDE must have:

  1. Tabs
  2. Split Layout
  3. PRegex Find and Replace
  4. Highlighting and indenting

The features that are nice to have:

  1. Column Select
  2. Plugin Architecture

Most modern IDEs have all of these, and more. So if you want to learn LISP, forget about EMACS, EMACS sucks, it sucks clown shoes. People who like EMACS are ugly, and stupid, and they need to wake up and join all of us in the 21st century. However LISP is not ugly, or stupid, and it is already in the 23rd Century.