Thursday, January 07, 2010

Git 'er Done

I've finished looking over the "Why Git is Better Than X", and the propaganda pages from Bazaar and Mercurial (propaganda is good, you need to say why you think your system is better).

I think I had previously decided on Bazaar. I was really worried about Git on Windows, and Git's main features "Cheap Local Branches" and "The Staging Area" didn't impress me at the time. Bazaar has some really nice support for implementing different sharing schemes on top of the distributed model.

But now, I think Git is the way to go.

In my day-to-day work, I have at least three "local branches" in svn. They are:
  1. the working trunk - attached to the trunk, with all the changes I am thinking about making
  2. a clean trunk - this is my "Staging Area" where I copy changes in before commit
  3. an old copy of the trunk - for comparing really old revs (because history is not available offline in svn)
  4. a personal branch - for long term projects to make major changes
  5. a release branch - for when we are doing a public release
Each local repo can take up to 2 GB (if I need to build the executable). Wasting disk space isn't the biggest worry. It takes a long time to set up these repos, and a lot of work to keep them all in sync and up to date.

I really overlooked the Staging Area.

My concern was that I wouldn't be able to use it, because I need to test any changes before pushing anyway. Of course, I realized that I just need to push to my clean area, test there, then push to the "main" repo (as much as any repo is main in a distributed SCM).

Wednesday, January 06, 2010

Stuff I've read lately

"A is for Alibi" (Sue Grafton)(audio) - This is the first in the "Alphabet Murder" series. It's interesting to see how Grafton has developed as a writer.

And it is good they replaced this narrator.

She is terrible.

She has two tones - monotone and slightly deeper monotone. For an audio book, you need at least two distinct tones, so you can figure out when the speaker changes in a dialogue (basically, to denote the paragraph breaks). Distinct voices for each character and one for actions is a plus, but not absolutely necessary.

A lot of the time, I couldn't figure out who was talking - even if I was paying attention. And if distracted (say, by a crazy MD driver), it was easy to get lost. Sometimes it was hard to tell if someone was speaking or if something was happening.

That said, the story was ok. Grafton drifted some into "romance novel" territory, which she is obviously terrible at. Good to see she has dropped it in the later novels.

Tuesday, January 05, 2010

New Stars Status

So close now!

It's been a while since we had a Windows screen shot. See, it still looks the same! :)

I had to scp over the turn file from Linux for debugging, because I don't have a split case on Windows, and debugging through VNC can be a pain...

This looks like the normal split case, but look carefully...

The original fleet id is 234806..., now the fleet id is different. I did a split, where all the ships move into the new fleet (and the old fleet gets deleted). That was to test the fleet deletion code, which is needed for merge to be useful.

Now I can do merging.

Monday, January 04, 2010

Give in to the Darcs Side

Continuing from my last post, I did want to talk about SCM I will not be considering:

Darcs
  • Written in Haskell, considered the poster-program for Haskell. Haskell is a functional language, similar to ML. Given the horror of ML, and the behavior of Darcs - I am not motivated.
  • Operates on a "theory of patches". Finding the right set of patches, and applying them in the right order. I don't believe it is possible for a machine (currently) to handle this level of complexity. Heck, I don't know that I can handle the complexity!
  • Ate our repo, twice. Losing the repo is an unforgivable sin for SCM.
  • Was really slow. They are supposed to have fixed the number of "exponential merges" (nice). But it was slow all the time. The exponential merges were just insult to injury.
BitKeeper
  • Commerical software. No way I am going to pay for software for my personal projects.
  • Also ate the repo. Maybe twice.
SVN
  • No distributed model
  • Logs and history are not available offline
  • While creating branches is now easier than CVS, merging them back is still just as hard (this is a hard problem, so I don't blame them)

Sunday, January 03, 2010

Source Control to Major Tom

To a coder, nothing is more precious than his code. Source control management (SCM) is all about keeping your code safe. Not against disk failures, so much as against bad edits ("what was I thinking!" !). It's also a good place to stash some forms of comments (not what the code is doing, but why it was written). Mixing this into the code can be distracting. SCM also provides a nice log of when features were added ("it's been two years!?").

I had my first encounter with source control as an intern at Intel. Our files were under CVS (concurrent versioning system), with some binary files directly managed with RCS (CVS started as a wrapper around RCS - all those funny ,v files).

CVS is ancient (1990), and works really well. You have to be careful with merging conflicts, tagging takes forever, and branching is so confusing no one ever used it. You have to stretch the meaning of "really well"...

Eventually (about ten years ago), some people decided to improve on CVS. That project is called Subversion (svn). I didn't use Subversion until about two years ago. SVN is a big improvement over CVS. The main thing - being able to do a diff against a network repo while not connected to the network. Also, SVN is much better with merging. Tags and branches use the same mechanism, which is cheap and easy. Very nice.

I used CVS professionally until about 2003. That was when I was exposed to the Great SCM Wars - between minions of Darcs, and keepers of BitKeeper. I will have to rant about them sometime. Suffice to say, that no man has ever fought with them and lived! The bones of many projects lie strewn about their lairs. So if you do doubt you courage, come no further. For death awaits you all; with nasty, big, pointy teeth.

Ok, so I still use CVS for my personal projects. I would like to switch over to something new, probably "distributed". There are three alternatives:
  1. Git - created by none other than Linus of Linux fame. He too was a victim of BitKeeper, so he is familiar with pain. He is a really smart guy who churns out quality software at a prodigious rate. He also tends to be a little quirky, and he is (ultimately) writing software for himself, so there is no guarantee I will get the same returns...
  2. Mercurial (hg) - apparently started about the same time as Git (2005), for the same reason (holding the Linux kernel tree)
  3. Bazaar - the newbie in this line up (2007, and new is bad, like in compilers - new means buggy and untested). But, I am willing to give it a shot.
I had previously compared these three and decided on a winner. Sadly, I can no longer remember which one I picked. And things have changed some since then. At the time, Git was basically Linux only (there was a Windows hack by some guy who was trying madly to keep up). Now, I can get Git as a Cygwin package.

I will have to go through again and compare. I don't think SVN is in the running, as it does not have a distributed model. I like the distributed model, because it allows me to push code from one machine to another without having to worry about which one is the "master".

Saturday, January 02, 2010

The Bootstrap Problem

When you turn your computer on, it just boots. You take it for granted. It says "Windows loading" or "Grub", or "L..I..L..O".

But a lot of work goes into getting your computer to boot.

The main problem is the processor just runs programs. And it needs a program to tell it how to load programs. But you need to load a program, to run the program...

The solution is a program which lives at a particular address in permanent memory (ROM). This program is called the BIOS, and it has a really remarkable history going back to the original IBM PC.

The BIOS finds a boot device (usually floppy, harddrive, or CD-ROM, but now usually includes USB). It then loads the "boot sector". This is a 512 byte block of memory containing code which is placed at address 0x7c00. It then jumps to 0x7c00, and you're off!

In my NedOS musings, I considered using Grub as a boot loader. It handles a lot of stuff, and allows you to build your kernel like a regular program. In the end, I rejected it, because:
  1. I wanted to learn how to do a bootloader
  2. I didn't want to be bound to ext2fs and Elf (or worse, FAT32 and PE)
  3. You really need to build a cross compiler to use it
  4. Grub seems bound to 32bit kernels
  5. Grub is 3 stage, I wanted to see if I can get into 64bit mode in 1 hop
The fifth point is the most interesting. Your first stage is the bootsector (512 bytes, really 448 on a boot floppy). That's all you've got to get going, it is really cramped! But loading a second stage requires disk accesses and some sort of file system. I don't want to think about file systems right now, and I don't want to pick an existing one and get stuck with those assumptions.

After most of the day hacking, I have a minimal 64bit bootloader, in 170 bytes!

Now I need to figure out what BIOS info I want to extract before kicking into protected mode, and how I want to find the kernel.

Ugly/cool tip:
You cannot get to 64 bit mode in one step. You have to go through protected mode (because the bit for long mode is in a different register than the register used to enter protected mode - jerks). Further complicating things, the code descriptor for 32bit code is incompatible with the descriptor for 64bit code (nice work guys).

So what I do:
  • set the descriptor for 16bit protected mode code (yes, the original 286 style)
  • kick into protected mode
  • set for long mode (I'm now in a really tenuous position, but interrupts are off)
  • flip the descriptor bit for 64bit code
I could switch to 64 bit mode now, but I turn on paging first, just for good measure. Then with a far jump, I'm into 64 bit/paged mode!

Friday, January 01, 2010

Debacular

When something turns out really bad, you say it was a debacle. If you're in the middle of something that you know is going to end badly, you say the whole process is debacular.

So, a post on comp.arch led to a Google search, which led to a website called OsDev. Now, I have a directory in my projects area called NedOs, which I have been trying to figure out what to do with. There's really not much stuff in there, but it seems a shame to delete it. So, why, not, you know, write an OS? It's not like I'm hugely busy in every dimension, right? (mmm, debacular already)

I broke out my Intel software developer manuals, but they are all so old, they don't have 64 bit stuff. I downloaded the new one, and was greeted by this:

Now, that is debacular!

For anyone who is thinking of writing their own OS, this is the flow chart for enabling "Long Mode" (that is - X86-64, AMD64, EMT64T, or as Intel has now started calling it IA32e mode!) (technically it handles all the modes)

After staring at it for a while (I just want 64 bit mode with paging, is that so wrong!), I realized this could be three sentences:
  1. Enable PAE
  2. Enable LME
  3. Enable PG
You could have an optional fourth sentence - "The first two steps can be done in any order."

So, this picture is worth, like, -994 words.

Thursday, December 31, 2009

New Stars Status

Oh Frabjous Day! Calooh! Callay!

Here we can see the fleet split dialog in action. The cool thing about Tcl, is the whole dialog and the logic behind it is 90 lines of code...

Here's the bulk of it:
for {set i 0} {$i < $numDesigns} {incr i} {
pack [frame .tSplitter.fTop.fRow$i] -side top

set shipName [newStars $::ns_planet $fid $::ns_design $i $::ns_getName]
pack [label .tSplitter.fTop.fRow$i.lL -text $shipName] -side left

set shipCt [newStars $::ns_planet $fid $::ns_design $i $::ns_getNumFleets]
pack [label .tSplitter.fTop.fRow$i.lLC -text $shipCt] -side left

pack [button .tSplitter.fTop.fRow$i.bL -text "<" -command "adjustSplitRes $i -1"] -side left
pack [button .tSplitter.fTop.fRow$i.bR -text ">" -command "adjustSplitRes $i 1"] -side left

pack [label .tSplitter.fTop.fRow$i.lRC -text 0] -side left

lappend ::splitRes [list $shipCt 0]
}

Hardly any < or >!

In English, it says:
foreach ship design in the fleet do
create a new frame (invisible GUI packing object)
pull the ship name via the C++ bridge, and make a text widget for it
pull the ship count via same, and make a widget for it
make 2 buttons, one < and one > which will call adjustSplitRes (described later)
make a text widget with "0"
append a list to the global variable splitRes (which holds the split counts for each design)

Like 9 or 10 lines of specific English, roughly the same in Tcl (plus whitespace)
Here's adjustSplitRes in its entirety:
proc adjustSplitRes {row val} {
set left [.tSplitter.fTop.fRow$row.lLC cget -text]
set rght [.tSplitter.fTop.fRow$row.lRC cget -text]

if {$left < $val} {return}
if {$rght < -$val} {return}

set left [expr $left - $val]
set rght [expr $rght + $val]

lset ::splitRes $row 0 $left
lset ::splitRes $row 1 $rght

.tSplitter.fTop.fRow$row.lLC configure -text $left
.tSplitter.fTop.fRow$row.lRC configure -text $rght
}

This pulls the text labels for the left and right, checks for underflow, then applies the new count (for now, we only support moving up or down 1, but I should be able to bind shift and control click to move more). I then update the splitRes list, and the GUI text.

The C++ bridge does not handle deleting the old fleet... that will probably need to be fixed, although we should have new tools for handling chaff mine sweeping, which was the main reason for shedding old fleet nums (otherwise, you never need to move out the last ship from a fleet).

I should be able to use much of this logic to build the fleet merge dialog.

Split all and Merge all should be easy, and aren't strictly needed for playing (merge fleets is needed).

Almost there!

Monday, December 28, 2009

Stuff I've read lately

"O is for Outlaw" (Sue Grafton)(audio) - Meh.

Saturday, December 26, 2009

Black Hole Catalyzed Total Conversion

That has a nice ring to it. Kind of like "Laser Induced, Gravity Sustained Fusion Reactor".

Weird chain of events: a Slashdot article discussing the physics of space war. Leads me back to Project Rho, re-reading the sections on stealth and heat dissipation. Somehow, I ended up on stardestroyer.net, reading about the Death Star power system (I remember something about the importance of heat dissipation, and how Luke might not have had the impact he thought he did). Someone (maybe there, maybe elsewhere) mentioned the possibility of using black holes to convert matter to energy (this was in the context of a system failure not producing a tremendous boom, at least in comparison to the enormous power output before the failure [the Death Star is assumed to produce more power than Sol - blowing it up could easily wreck a solar system - that is, Yavin or Endor, places the heroes were supposed to be protecting]).

I decided to sit down and actually look at what it would be like to have a black hole around for energy conversion.

The idea is actually pretty simple, you feed matter into a black hole (presumably one already electrically charged so you can keep a handle on it). You then harness the Hawking radiation (HR) for energy.

There are several properties of black holes which make this not entirely unreasonable:

Power output (via HR) is inversely proportional to the square of the mass of the hole.

That means every (log) step down in mass, you go up two steps in the power of your reactor! Smaller holes give more power! It also means the black hole will likely not fail-big, but rather fail-evaporate (giving off a huge amount of energy). A small hole (2e10 kg) would produce about 1e11 W. Making it a little smaller (2e8 kg) would yield 1e15 W (probably too much to get rid of...)


Size is proportional to mass

This has good and bad points. A small hole is really small. 2e10 kg being about 3e-20 m (3e-11 of 1 nm) This means you won't accidentally fall in. But it also means you have to try very hard to get matter into the thing to keep it going.


Lifetime is proportional to mass cubed

This is kind of annoying, but the constants make it ok. A small hole (2e10 kg) would have a lifetime of about 21 million years. It does mean that your initial hole (unless you have a really big accelerator) is going to decay fast.

Actually, with a lifetime like that, it's effectively a battery, with no fuel input. A super small hole (2e6 kg, only two million kilograms!) would have a lifetime of 662 seconds! Definitely a problem, especially considering it is giving off a constant 1e19 W! Don't get burned!


People worrying about the Large Hadron Collider producing black holes shouldn't worry. The energy levels are way too low to produce a hole with any meaningful lifetime. It also means we will need a much larger collider (or better production methods - huge lasers?) to produce commercial black holes.

Wednesday, December 23, 2009

Civ Sequels

Of course, a game as successful as Civ is going to be followed by a lot of hangers-on (both products from the original designers, and imitators).

There was the natural progression: Civ-Net, Civ 2 (with a lot of variants, like Test of Time), Civ 3, and Civ 4.

There were clones: Civ Call to Power and Free Civ.

And in-spirit successors: Master of Orion (were you start with one planet and one colony ship), and Alpha Centauri (where you play the descendants of the original colony ship from Civ). Also, Colonization: a Civ-like specialized to a particular time.


The natural sequels were actually very disappointing.

Civ-Net: largely a Windows port (there may have been a Civ-Win). The network play had sequential (basically, hot-seat on different computers), or simultaneous. This really didn't work out, as a battle between two catapults could be decided by who was quickest with the keys.

Civ 2: Civ plus-plus. More of everything. More tech, more units, even more for settlers to do (double irrigation, anyone?). Of course, more is not necessarily better. The micro-management hassle of Civ became that much more in Civ 2. With more city improvements and more engineers needed, you built more cities. And the tedium of terraforming became just that much more. I largely play Civ 2 now, only because the old DOS Civ is a little buggy (some sort of weird memory corruption).

Civ 3: A good disaster. Introduced a lot of new concepts (culture, armies, a focus on fewer/better cities). I'm not sure what went wrong, had to be not enough play testing. Armies were way to powerful, culture didn't work quite right, the corruption in big empires was just crippling and small empires couldn't win.

Civ 4: Another hit. Largely made possible by the failures of Civ 3. Now culture is working right, the combat model is a lot better, and small empires really work. They also managed to fix the terraforming problem, where there is an actual choice to be made (not just, road-irrigate-railroad / next!). I'd play this more, except the graphics requirements are really steep.

Tuesday, December 22, 2009

The Life of the Game Designer

is not an easy one.

You have to spend hours thinking about (i.e. reminiscing) about all the great old games. Maybe talking with friends, or on rec.games.design, or even just alone.

Then, you have to go and play all sorts of games (for, you know, "research").

In that spirit, I have been playing some of the Facebook games (which a lot of people say are really bad).

They are really bad.

I will break out the how and why in (one or more) separate posts.

Monday, December 21, 2009

The Civ Legacy

I've been wanting to do some discussion of game design, and no better place to start than Civ.

Sid Meier's Civilization will always be remembered as a classic. You might say it is just Empire on steroids, or a translation of the board game - but millions of people don't play Empire and most have never heard of the board game.

Sid perfected "Just one more turn". Not only for Civ, but also in the less successful Alpha Centauri (lovingly known as SMAC).

The main advantage Civ had over Empire was splitting attack and defense (along with a more complex city model). This allowed specialization of units.

Civ also covered a much longer (and therefore more "epic") time scale.

The biggest failing of Civ was the old "phalanx beats tank" scenario. This comes from the simple unit progression (after the most basic unit - Militia 1/1):
Defensive



Phalanx12
Musketeer23
Rifleman35
Mechanized Infantry66

This is from memory, so I may be a little off. The general progression was just to add one or two to the attack and defense.

Offensive






Horseman21
Legion31
Chariot41
Catapult61
Cannon91
Tank105
Artillery12?

Sorry, I can't remember the artillery defense at all. It was less than the tank, making them very specialized (they could ignore city walls). Some of the offensive units could move at 2 (Tank may be 3, that has changed some in Civ, Civ 2, Civ 3, Civ 4).

The combat system was dead simple:
Chance of win = attack / (attack + defense)
So, a horseman attacking a phalanx has a 50% chance of winning. Of course, as a military option, a 50% chance isn't very attractive. I'm going to need an equal number of attackers as defenders, and defenders get an advantage for terrain and digging in ("fortifying").

I will cover naval combat in another post.

This is actually very easy to fix, although it didn't get fixed until Civ 4 (which, ironically, went back to a single strength number, although they did it very well).

Make the units improve by more than 1 per step! I mean, you've got at least a byte for strength and defense, that's 255 (or even 127 if signed).
In Civ 4, the "Modern Armor" unit is, like, strength 40. Plenty of firepower to crush that old phalanx.

Sunday, December 20, 2009

New Stars Status

I hacked in a simple fix for the case I can check. I will need more code once I can check more cases...


Now we can build multiple ships, and split them out one by one. The Tcl/C++ interface has everything we need (I created this case from the command line). I need to update the GUI to present it nicely.

Saturday, December 19, 2009

Sorry

I was going to do some New Stars stuff. But I was cleaning out my projects directory, and found some old code a friend sent me.

Of course, I had about three different versions from hard drive back ups and new computers, so I was reconciling them all and putting my changes into CVS (had to reformat all the code, you know).

I also fixed a bug due to wrap around, and added an alternate viewing mode.

Here is the normal view (it shows biomes - like desert, forest, etc):


Here is the alternate view (based solely on altitude):


Of course, all this map gen stuff made me want to play Civ. So I lost the day to Civ 2. Mmm, Civ 2.

Friday, December 18, 2009

New Stars Status



This is a particularly tricky set of code. I need to split off individual ships into a new fleet, and make sure the fuel and cargo are transferred proportionately.

Here we can see the 2 Toms have been split, but the fuel was left behind (as would the cargo)...

Wednesday, December 16, 2009

Stuff I've read lately

"P is for Peril" (Sue Grafton)(audio) - Choosing an audio book from the library is always hard. There tends to only be popular fiction, and I can't always concentrate on audio (with all the crazy Maryland drivers). So, I don't even want to choose "good" stuff.

This is the second Grafton book I've read (listened to). I wasn't at all happy with this one.

First, the red herring. Totally didn't fool me, not for a minute. In fact, I thought it was so overdone that it was actually the reverse. I figured the guy was being set up, and the main character's total hatred of him (after her initial liking him) would turn out to be misplaced. Nah, he was just evil.

The ending made no sense.

We had a lot of suspects to choose from:
  1. The ex-wife.
    • Gained $1e6 after his death
    • Significant circumstantial evidence
    • Spite against current wife
  2. The business partners
    • Protect their multi-million dollar business (blame him after he's dead)
    • He was going to the FBI (they might not have known)
  3. The step daughter
    • Conceal her drug habit
    • Conceal her theft of $30k
    • Escape her "constricted" lifestyle
The ending isn't totally clear (I listened to it three times, and I'm still not sure). You can sort of convince yourself that it was the step daughter, but I think the author intended to finger the current wife...
  • Gains nothing (life insurance went to ex-wife)
  • Loses the father of her two year old
  • Couldn't have wanted to get away (he was old and a workaholic)
Boo!

Friday, December 11, 2009

New Stars Status

I've been doing more work on the Linux side, as bugs come in and because I don't trust my XP regression (without comparing it to Vista).

This means I get my first Linux screen shot! (Which confused me for a second, I thought I would need to scp it back!)


Twm rulez!

The other advantage of working on Linux is that I need a new regression. That means I can use a disposable game, where everyone is not acting optimally.

Here, I have changed player two to build two scouts, instead of one.

That allows me to update the build logic to group new ships into fleets by design, rather than putting every ship in its own fleet.

This will allow me to work on the split fleet code.

Tuesday, December 08, 2009

Prime Directive

Let's see how D and C++ stack up when it comes time to maintain and expand our code.

I created a bash script to run the programs a lot (so we can check performance).

#!/usr/bin/bash
for i in {1..100}
do
./d_prime.exe > /dev/null
done

This isn't the greatest (generating more primes would be good too), but it should suffice...

On my Pentium 4, 2.4 GHz, D gives:
real 0m12.865s
user 0m3.888s
sys 0m10.450s

While C++ gives:
real 0m13.325s
user 0m4.128s
sys 0m10.667s

I won't be comparing the speeds directly, as much of that is a compiler issue (and I would need to evaluate turning on optimizations, which is a big headache). I am most interested in algorithmic improvements, and how hard they are to code.

The obvious thing is that the code is O(n^2), or at least O(n*p) where p is the current number of primes. We don't need to check primes that are larger than sqrt(n). So, how can we encode this?

The D code is an easy change:
We add:

uint ct = 0;
uint sqr = 4;
if( i >= sqr )
{
ct++;
sqr = primes[ct] * primes[ct];
}


And change:
if( isPrime(i, primes[0..ct+1]) )


This makes use of D's "slice syntax". That is, we can create a subarray just by specifying the elements we desire. The slice is a reference, so there is no copying.

real 0m12.915s
user 0m3.923s
sys 0m10.507s

The new time isn't any better, probably because the time is dwarfed by system (/dev/null doesn't seem any faster under Cygwin). But we have introduced a new algorithm that is potentially twice as fast with little effort.

When I come to the C++ version, I realize I've made a terrible error... the isPrime function takes a reference to a vector. But I only want to pass in part of my current vector. Now I have to come up with a slice class which is derived from vector, or change my function to use iterators (Note: I did not plan this to make C++ look bad!).

Iterators are ugly, but not as ugly as trying to implement my own slice class!

The new prototype is:
bool isPrime(unsigned n, const std::vector<unsigned>::const_iterator b,
const std::vector<unsigned>::const_iterator e)


and the for loop becomes:
for(std::vector<unsigned>::const_iterator i = b; i != e; ++i)


while the call point is:
if( isPrime(i, primes.begin(), primes.begin()+ct+1) )


Again the time isn't any better:
real 0m13.561s
user 0m4.097s
sys 0m10.855s

Of course, iterator addition is pretty unusual. It might give someone pause. And make them think about how it is just as ugly as normal iterator usage!

Now imagine I've had to edit header files and caused a dependency chain reaction which forces everything to rebuild. Or worse, altered a public API, which drives a version change. Maybe implementing that slice class wouldn't be so bad...

Sunday, December 06, 2009

D Code

I had a little time, and started playing with primes again (something fascinating about primes).

Good chance for a little D code:

import std.stdio;

bool isPrime(uint n, uint[] curPrimes)
{
foreach(i; curPrimes)
{
if( n % i == 0 )
{
return false;
}
}
return true;
}

void main(char[][] args)
{
uint[] primes;
primes ~= 2;

uint i = 3;
while( i < 1000 )
{
if( isPrime(i, primes) )
{
primes ~= i;
}
i += 2;
}

writefln(primes.length);
writefln(1);
foreach(j; primes)
{
writefln(j);
}
}

The C++ code is very similar (except with lots more editing for HTML, with &gt; and &lt;):

#include <iostream>
#include <vector>

bool isPrime(unsigned n, const std::vector<unsigned> &curPrimes)
{
for(std::vector<unsigned>::const_iterator i = curPrimes.begin();
i != curPrimes.end(); ++i)
{
if( n % *i == 0 )
{
return false;
}
}
return true;
}

int main(int argc, char **argv)
{
std::vector<unsigned> primes;
primes.push_back(2);

unsigned i = 3;
while( i < 1000 )
{
if( isPrime(i, primes) )
{
primes.push_back(i);
}
i += 2;
}

std::cout << primes.size() << std::endl;
std::cout << 1 << std::endl;
for(std::vector<unsigned>::const_iterator i = primes.begin();
i != primes.end(); ++i)
{
std::cout << *i << std::endl;
}

return 0;
}

I've already complained about hideous iterator syntax. But I will post more on some D goodness, when it comes time to make improvements to the algorithm.

Sunday, November 29, 2009

Fun With Excel

(Actually its the Open Office Excel clone, but I can't even remember it's name...)

Saturday night I got my development environment under Windows XP in workable shape (I won't say it is totally working, because there still seem to be some oddities).

I then started to look into the regression.

I am trying to run the regression like a real game, which means all the micro-management entailed in a new game (part of the reason for NewStars was the hope of eventually automating the micro-management).

I have a spreadsheet (the famous STARS!.xls), which allows for colony planning.

The spreadsheet is incredible, and is invaluable for checking the server code.

I found a bug regarding partial completion. Imagine a factory built 1 resource at a time, over 10 turns. The factory costs 4 germ. How do you subtract the 4 G, and not 0 or 10. Our code was subtracting 0...

After I fixed that, I found a (what I think is) a bug in the spreadsheet!

So, I spent all day looking at spreadsheets, and ending up starting a new spreadsheet.

Fun! Fun!

Tuesday, November 24, 2009

New Stars Status

Wow! A long time with no updates!

Real life has interfered with development, hampered by some irritating 64 bit problems. Apparently, the C runtime in Windows Vista accepts %ll for printf. The same cannot be said for Windows XP.

I had been doing most of my development on a Windows Vista machine, but lately have had to fall back to Windows XP. That's when I noticed the regression doesn't pass.

I tried to track down the printf's and replace them with ostringstreams (finally a case where C++ is better than C!), but there are just too many of them. I ended up doing:
vi `grep -l '%ll' *.cpp`
And
%s/%ll/%I64

Ahh, saved by vi.

The regression is now somewhat passing, but there are some oddities... need to check against Vista...

Sunday, July 26, 2009

New Stars Status

Getting close!



I added the "Other Fleets Here" GUI element. I also implemented the functions to populate the list.

As soon as I implement the functionality for split/merge and cargo, we will be ready for a developer test game!

Friday, July 24, 2009

Concepts Are Dead in C++0x

Long live Concepts in C++1x!

What are concepts? And what is C++0x?

C++0x is (in addition to being the worst name ever for anything) the next standards update to C++. It endeavors to add more to C++, not because C++ needs to be more complicated (which it already is, and which it will become more so), but to try and add some badly missing features to make C++ competitive with higher level languages.

Bjarne has a FAQ page.

Let's fisk the individual features he comments on:
  • "auto" keyword - good, D had this since version 1
  • for(auto x : container) - good, wordier than D version 1
  • fix for template<nested<>> - good to see this fixed, sorry for compiler and tool writers who need to make it work
  • default and delete - meh
  • enum class - good (if oddly named), D version 1
  • constexpr - good, D "pure" functions (maybe not until version 2) are more powerful
  • decltype - meh, I believe D has better introspection with typeof(?), etc.
  • initializer lists - not sure how much of a win this is, adds a lot of complexity. Built-in array types seems a better (simpler) solution
  • preventing narrowing - meh
  • delegating constructors - good, D version 1
  • in class member init - yeah!, D version 1
  • inherited constructors - meh
  • compile time assert - D version 1 (plus contracts are way better)
  • long long - ugh, why not standardize on int64_t?
  • nullptr - ugly name, D version 1 has null
  • suffix return type - "[] mul(T x, U y) -> decltype(x*y)" ahhh!!!!! that looks like ML or something else that Cthulhu would write
  • template alias - meh
  • variadic templates - much needed, although more complicated templates makes my head want to explode
  • more initialization syntax - cause more is better
  • rvalue references - wow, that is some ugly syntax. All hail swap!
  • union fixes - "s.~string();" nuff said
  • POD - meh
  • raw strings - meh
  • user defined literals - wow, I mean wow. Why? 'constexpr complex<double> operator "i"(long double d)' Why? Please, why?
  • attributes - seems good
  • lambda - yea! D version 1
  • local types as template arguments - never ran into this bug, good to see it fixed
  • C99 - meh
  • extended integer - why wasn't <stdint.h> enough?
  • extern templates - this is how some early template implementations worked, maintenance headache
  • std::array - D version 1
  • unique_ptr - nice
  • concepts - this would be nice. Much closer to what Java allows for its (much weaker) version of templates.
I have a lot of reservations about all this:
  1. More. More. More. It's all complexity-plus-plus. More complicated compiler, more bugs, more complicated IDE, more to learn, more to remember, more to code. Maybe a little less to code, sometimes. Ugh.
  2. A lot of this is no longer looking like C. What is some embedded guy who misses this update going to think when he sees this code? He'll have no idea what is going on.
  3. How long before I can actually use this stuff? Sure, g++ will have it quickly... MSVC will probably take 3-5 years after the standard (because they will keep trying to push their incompatible version). What about dmc? Or weird embedded compilers whose vendors have gone out of business? Oh, they'll never have this... which means, I shouldn't be using it if I need to be cross compatible. Which means I can't use it for the next 10 years.
  4. All this to get what D had in version 1. D version 2 will be done in the next year, and usable from day 1.

Tuesday, July 07, 2009

New Stars Status

Wow, a big change, not very fun, I was putting it off for a long time...



Notice the Long Range Scout is now named #1274... I have converted the ship design and fleet ids to follow the map given in my Sourceforge post (planet ids were the same before and after).

This revealed a bug that Cygwin Tcl 8.4 does not honor wide ints as 64 bits. It compiles, but apparently just gives you 32 bits... ugh. Then I had to switch everything over to -mno-cygwin, rebuild everything, and use the ActiveState Tcl (which is 8.5).

Since the new object id code makes use of rand, all the planets changed (which means I have to redo all the player orders). So, I took the opportunity to sort in the additional names John sent months ago. We now support ~2.5k planets with names. We will probably need an automated scheme for larger universes (which would probably be populated entirely by AI's, who aren't going to care about planet names).

I changed the fleet name label to left align. This is a little ugly for the shorter planet names, but it is much better for the longer fleet names. I also fixed a bug where fleet path highlighting would remain when you switch to a planet view.

Friday, May 29, 2009

The Horror Returns

I last complained about C++ back in September (on the 20th and 21st). I thought I had seen all the horrors that the new template error checking could produce.

I was wrong.

Check out the new spewage from g++:

main.cpp: In member function `void Test<t>::test()':
main.cpp:11: error: expected `;' before "i"
main.cpp:11: error: `i' undeclared (first use this function)
main.cpp:11: error: (Each undeclared identifier is reported only once for each function it appears in.)
main.cpp: In member function `void Test<t>::test() [with T = int]':
main.cpp:20: instantiated from here
main.cpp:11: error: dependent-name ` std::vector<t,std::allocator<_chart> >::const_iterator' is parsed as a non-type, but instantiation yields a type
main.cpp:11: note: say `typename std::vector<t,std::allocator<_chart> >::const_iterator' if a type is meant


Not bad, 8 lines (some very long) for a 24 line program! Oh, and can I say how much I "love" the <> syntax for templates when it comes time to post into HTML (of course, C++ predates the web, so I can't blame Bjarne too much :)

Here is "teh codz"

#include <vector>
#include <cstdio>

template<typename T>
class Test
{
public:
void test(void)
{
std::vector<T> v;
for(std::vector<T>::const_iterator i = v.begin(); i != v.end(); ++i)
printf("%p\n", &*i);
}
};

int main(int argc, char **argv)
{
Test<int> t;

t.test();

return 0;
}


Line 11 is the 'for' loop. g++ is complaining about the declaration for 'i', which is the standard (ugly) iterator. The note must of been added after lots of people complained.

The core of the error is "parsed as a non-type, but instantiation yields a type". It means that because it uses <T> somewhere, it must be parsed as a non type (that is, g++ has no idea what the type could be at this time). However, it is being used to declare a variable - which must have a type. So, g++ is confused.

The note tells us how to fix it:

$ diff main.bad.cpp main.cpp
11c11
< for(std::vector<T>::const_iterator i = v.begin(); i != v.end(); ++i)
---
> for(typename std::vector<T>::const_iterator i = v.begin(); i != v.end(); ++i)

Thanks diff for more < and >! (also predates HTML, so maybe HTML is to blame...)

Of course, if the compiler knows what the problem is well enough to emit the note, and the fix is so easy, makes you wonder why the compiler can't just fix it for you...

Thursday, May 28, 2009

Lua

I have been hearing a lot about Lua. Apparently it is very popular in game development circles. I love to read about the history of things, and Lua has a nice page for that.

They say:
"The main contenders were Tcl and, far behind, Forth and Perl."
That's pretty interesting to see. What made them not use Tcl?
"In 1993, Tcl and Perl ran only on Unix platforms."
That's a real shame. I was introduced to Tcl in 1999, when there was already a Windows version. I'm not sure when the code was first ported to Windows, I found a Usenet post from comp.lang.tcl called "New Release of TkWin -- Tk for Windows" discussing version 0.2, from Jul 18 1994. Incredible to think there may not have been a Lua by so slim a margin...

So, could Lua be a replacement for Tcl for me?

Lua feels like "everything is a table". This causes the problem that tables are not a primitive type, so there are also types for numbers and strings (as well as boolean). The syntax is vaguely C (actually more Pascal).

The use of tables seems to give easy access to object oriented programming. That is something Tcl is weaker on (mostly from the "too many choices" problem). I'm not too concerned about OO in my scripting. Scripting is for fast development, OO is for structure and maintenance.

I think I will pass on Lua for now.

Wednesday, May 27, 2009

Iterators::end

The greatest benefit of moving vectors and maps into the base language is an improvement in the syntax for iterators.

For example, C++:

std::vector<MyCoolType*> myVec;
myVec.push_back(new MyCoolType);
for(std::vector<MyCoolType*>::const_iterator i = myVec.begin(); i != myVec.end(); ++i)
(**i).print();


Versus D:

MyCoolType[] myVec;
myVec ~= new MyCoolType
foreach(i; myVec)
i.print();


First, the differences:
  1. Every class reference is automatically a pointer (MyCoolType[], not MyCoolType*[])
  2. Binary operator~ is used for vector concatenation (an object is promoted to a vector of size 1)
  3. Pointers to structures can use '.' It's obvious that the pointer needs to be dereferenced.
  4. "foreach" allows automatic const iteration. There is "foreach(ref i; myVec)" for non-const.
The advantages should be clear. Iteration in C++ is an abomination. Typedef's can clean things up some, but they also obscure what is really happening (error messages will likely come back as the underlying types).

I have become inoculated to these problems, partly because the Visual C++ IDE makes it easier (with auto complete). D makes it possible to be productive in Vi again... (not every machine has VStudio)

Monday, February 23, 2009

STL::collapse

A simple addition to C (variable length arrays using the [] notation), allows the removal of std::string and std::vector.

The question becomes, "how much do we really need from STL"?

From personal experience, the most used classes are std::string, and std::vector. The next is probably std::map (although std::list is handy, but vector can do most of it). Keep in mind, Tcl gets by with just string and maps of strings to strings...

D uses a simple concept to add maps.

char[][char[]] strStrMap; // a map from string to string
int[int] intIntMap; // a map from int to int
char[][int] intStrMap; // a map from int to string


The usage is just like it looks:

strStrMap["hello"] = "world";
intintMap[6] = 4; // Craw Giant
intStrMap[0] = "trample";

Sunday, February 22, 2009

Native Vector

I think the D Faq makes my point for me:
"the implementation of a string type in STL is over two thousand lines of code, using every advanced feature of templates. How much confidence can you have that this is all working correctly, how do you fix it if it is not, what do you do with the notoriously inscrutable error messages when there's an error using it, how can you be sure you are using it correctly"
Vectors are built in to D:

char str1[8]; // eight chars, enough to hold a string of length 7 and the 0 terminator
char str2[]; // a variable size string
char *str3; // a C style unknown length string


D strings are not NULL terminated (although string literals are given an extra NULL byte so that they can easily be used as C strings). This allows substrings to be referenced in situ. String length is determined using the vector length.

D is also able to avoid a pitfall of Java. When Java was developed, Unicode was all the rage. So, strings in Java are all Unicode (2 bytes). That means every string is taking up twice the memory of a C string.

D uses UTF-8 (which I've only learned of recently, Wikipedia says it was first presented in 1993 - Java was started in 1991). That means we can get all the juiciness of foreign characters sets (Hebrew and Greek being of interest to me lately), without the 2x memory penalty.

Saturday, February 21, 2009

Native String

The lack of native support for strings in C++ was a determined decision on the part of Stroustrup (I'd love to read his book on the history of the development of C++).

It is largely this decision which has made C++ everything it is (good and bad). Templates are driven by the need to implement vectors, so that strings can be vector<char> (or vector<short> for unicode). Allocation and comparison get added to the template implementation, which requires default parameters. Horribly long and ugly template definitions (std::vector<char, std::alocator, std::traits<char> >::basic_function, etc.) lead to changes in error detection and reporting.

What if we take a step back.

What if we look at a few simple additions to C, that will bring in some of the functionality people have come to enjoy in higher level languages (and what functionality is "good", how do we define "good").

Friday, February 20, 2009

std::string

I was reading the Daily WTF (which is can be a great learning resource on the potential horrors of any programming language and development system).

I saw the most incredible claim, "C/C++ has no native support for such a structure [strings]. It's only in the STL.".

Err, yea, it's hard to do C++ nowadays without the STL.

You might think this code won't work:

std::string arg("Hi me");
if( "Hi me" == arg ) { printf("Yup"); }


But it resolves to
operator==(const char*, std::string &);


Of course it leads to the horror I have to deal with:

Ret myFun(const char *charp)
{
FX::FXString foxStr(charp);
randomFoxFun(&foxStr);

std::string stlStr(foxStr.text());
randomStlFun(&stlStr);

// convert STL string to Fox String
// convert STL string to char*
}

Thursday, February 19, 2009

Stuff I've read lately

"March Upcountry" (John Ringo and David Weber) - I was looking for more John Ringo. This series is in the library under Weber. I wasn't sure if it would be more Weber or Ringo. I would say it is more Ringo's style. Straight up marines slogging through enemy territory. Well done.

Sunday, February 01, 2009

Stuff I've read lately

"Manxome Foe" (John Ringo) - This is the third book in the "Into the Looking Glass" series. This is really excellent space opera. Ringo is pacing himself nicely - I think he will be able to avoid painting himself into a corner (ala Peter Hamilton's Reality Dysfunction). Good space combat and marine boarding action scenes. The right mix of humor and seriousness.

Friday, December 12, 2008

Stuff I've read lately

"Ghost" (John Ringo) - I wasn't happy with this one. More Tom Clancy than SF. Also, the whole middle of the book is like a weird ad for kinky sex. Not sure what Ringo was trying for. But, I guess you have to give extra points for the main character killing Osama Bin Laden and sending his head to President Bush...

Wednesday, December 03, 2008

Stuff I've read lately

"Von Neumann's War" (John Ringo) - This is a standalone novel. It covers an invasion of the solar system by self-replicating robots (ala a proposal by Von Neumann for a method for us to explore the galaxy). Fortunately for us, the probes programmers didn't expect concerted, intelligent opposition - humans are able to reprogram them just in time to prevent our extermination. Think "Independence Day", with more marines and less Jeff Goldblum.

Saturday, November 29, 2008

Stuff I've read lately

"Vorpal Blade" (John Ringo) - This is the second book in the series starting with "Into the Looking Glass". Ringo is doing an excellent job of building up a rather unique space opera universe. Pretty hard SF, with good characters and the right mix of humor (like, a giant alien squid trying to eat their space going submarine!). I'm looking forward to more.

Wednesday, November 19, 2008

Stuff I've read lately

"The Family Trade" (Charles Stross) - I have been loathe to start in to these, as they are marked "Fantasy". I haven't read any fantasy in a long time (in all starts to be the same after a while). Sadly, Stross seems determined to continue this series...

That said, this book feels a lot like a hard SF version of "Chronicles of Amber" - so, that's good. For example, once the main character gets back from her first "hell ride", she starts planning all sorts of experiments and evidence gathering!

Tuesday, November 18, 2008

New Stars Status

Some big changes in store (not much visually...)



Here we can see the recent files list. It does not re-sort when you select a previous file (I am undecided whether that is a good feature or if some sort of better LRU might be nice).

I also fixed the C++ code to use 64 bit numbers when interfacing to Tcl. I think that just went in to Tcl 8.4. That will get things ready for the object id redux.

Finally, I fixed the new game wizard to actually generate the turn files when you start a new game. That is much better than having to save out the new game def, switch to a terminal, and do a 'newStars -n', then switching back to the client...

Sunday, November 09, 2008

Stuff I've read lately

"Into the Looking Glass" (John Ringo) - This is the first book by Ringo that I have read. It was pretty good. Kind of a mix of David Drake and some harder SF guy (Niven?). The story is about a physics experiment gone horribly wrong. The initial experiment blows up UCF, and starts opening stargates to all sorts of different places. Soon, evil aliens start pouring through some of them. Lots of action. In the end, they have to nuke Eustis.

Ringo had an interesting weapon system, a "quarkium bomb" or "quark ray". The exact mechanics weren't clear, but it was supposed to be more powerful than anti-matter. So, it can't be that the quarks are the direct objects converting to energy at the target (that would be equally powerful). Perhaps there is some way a form of quarks could trigger a chain reaction of disrupting nuclei. That would be scary...

Saturday, November 08, 2008

Tcl and Ini files

The NewStars client GUI is proceeding pretty well. I am finally getting tired of navigating from the client start directory to the regression directory (up two! src/testfiles/twop).

This is the implementation for the "Recent file list" in Tcl:

Create the resource file if it doesn't exist, or process it if it does:

if {![file exists [file join ~ $resourceFileName]]} {
close [open [file join ~ $resourceFileName] w]
} else {
eval [read [open [file join ~ $resourceFileName]]]
}


The ini file is a series of Tcl statements. That way, I can just "eval" the file to bring it in.

Then to handle saving the preferences:

rename exit origExit
proc exit {} {
set f [open [file join ~ $::resourceFileName] w]
foreach n [lsort [array names nsGui::prevFiles]] {
puts $f "set nsGui::prevFiles($n) \{$nsGui::prevFiles($n)\}"
}
origExit
}


The previous files is a map from the numbers ("1" to "9") to full path filenames. I can grab all the set values (which may be none) and write them out to that file.

By renaming "exit", I can trap any point in the program that is trying to exit. That way, I'm sure that the preferences are saved.

Wednesday, November 05, 2008

Improving C

A lot of programming languages have been inspired by C. I can easily list C++, Java, and D; there's probably more (Wikipedia lists Perl, I think Perl is a very different sort of C - and Python and Ruby feel more like cleaned up Perl. I always thought of JavaScript as more like VisualBasic, which is more Pascal-ish - Pascal being a sibling of C, both derived from Algol). There is a pretty cool family tree of programming languages, which shows Python as independent of Perl. I'm not too familiar with Python...

C is a pretty good language. Developed in 1972, it served as a sort of "cross platform assembly language". It allowed UNIX to spread to many different computer systems and provided fertile ground for thousands of hackers.

The main problem with C is the lack of support for object inheritance (you can actually do object oriented programming, but it is kind of a pain). But to implement object inheritance, you must relax pointer conversion warnings (I'm not sure how strict modern C compilers are on pointer conversion, C is classically very relaxed).

The other problem is the lack of generic programming, sometimes called template programming. This allows one set of code to work with various underlying types. The most obvious application is in basic data structures and common algorithms (vector, map, sort). Sorting through void* and size is kind of a pain...

Tuesday, November 04, 2008

Language is a Tool

Is it right to make fun of a programming language? I mean, "it's just a tool". That's what everyone says. You don't mock a hammer for not being a screwdriver (although screwdrivers can be usable hammers ;)

Of course, language is more than a tool.

It is also a means of communication, which means that you've got multiple entities involved.

The main communication is from the programmer to the computer. That means:
  • The programmer needs to be able to express himself efficiently (in a matter which makes sense to him, in a reasonable amount of time)

  • The computer needs to be able to understand (computers are really bad at English! and not just because English is a terrible language for specifications!)
But, programmers also communicate with one another. If I write all my programs in Tcl, not many other programmers can read them. That's a big part of the "more than a tool". If someone develops the "super monkey hammer" that can build a house in a day, but only super-monkey-hammer technicians can change the light bulbs; people are going to be frustrated.

Monday, November 03, 2008

Steam INNN SPAAACE!

So, I've been thinking about the space elevator, mostly about powering the climbers. Everyone seems to be backing laser power (using ground based lasers to shine on solar panels on the climber).

And, I've been reading Ken Macleod's "Fall Revolution" books, which have "steam launched spaceships". I read them completely out of order, so I never got any details. There is a little in "The Space Fraction".

After looking into it more, I found an excellent source. "Steam" propulsion is somewhat of an exaggeration. The recommended propellants are hydrogen and nitrogen. Water is possible, but not optimal.

But pretty cool, for small scale, high volume launch capacity.

Sunday, November 02, 2008

New Stars Status

Tada!


A lot of visual changes!
  • Fixed a bug in the defenses calculation (max at 100, please!)
  • Implemented hab view mode (circles represent current hab value, flags show ownership)
  • Fixed unexplored planets to show gray (both views)
  • Fixed the bug I knew would be there when removing too much
  • Fixed a bug when adding multiple items to the top of the queue (visual bug, data was ok)
  • Fixed the mineral labels to be colored (iron - blue, etc). I made the germanium one more gold than yellow. I find that yellow hard to read...
  • Added view planet window (shown, missing mining rates, capacity, hab value, and production queue right now...)

Saturday, November 01, 2008

Stuff I've read lately

"The Star Fraction" (Ken Macleod) - This is apparently the first in the "Fall Revolution" series. I didn't find anything new and incredible in here. It did give a little more insight into the "steam rockets" mentioned in the other books. That is worthy of its own research...

Friday, October 31, 2008

I Love Tcl

So, I have been grinding through a lot of GUI code (NewStars update coming soon!)...

In the process, I have been shifting code from C++ to direct XML access. Part of this involves something called "XPath" (which I had never heard of before).

The key is, you can query an XML document like a database (including wildcard and logical test patterns). So, if I want the node with the planet with object id stored in variable 'pid', I can do:

set n [$nsGui::turnRoot selectNodes //PLANET_LIST/PLANET\[OBJECTID=$pid\]]

'//' means a relative search (not necessarily from the root). I need "PLANET_LIST" because there is another list of planets, called "UNIVERSE_PLANET_LIST". The outer square bracked "[]" are part of Tcl (execute this part, and resolve it to the string that is returned). The inner (escaped) brackets are part of XPath (return nodes which satisfy "[logical_condition]").

Of course, any language can support XPath. But, in Tcl, I can open a console session, source the stars.tcl, and start issuing XPath commands against the turn file. That allows me to rapidly tune my request to get the results I want (eliminating the compile/re-run steps). Especially since the W3C XPath docs are unreadable...

Then, once I have the planet node, I can pick off attributes:
set concs [$n selectNodes string(MINERALCONCENTRATIONS/text())]

That replaces:
set planXML [xml2list [newStars $::ns_planet $id $::ns_getXML]]
set mainXML [lindex $planXML 2]
set cargoXML [findXMLbyTag "CARGOMANIFEST" $mainXML 2]
set tuple [lindex $cargoXML 1]


Especially since that used "xml2list", which can't always parse some XML...

Thursday, October 30, 2008

Const Fail

I only recently discovered an oddity in the C++ "const" feature. Consider this code:
class Foo
{
int *i;

void foo(void) const
{
*i = 4;
}
};
(I've left out some boiler plate)

Anyone see it? A const function is changing the state of the object!

Oops, turns out C++ const is not "transitive" (the D docs call it "head const").

This bit me big time on my previous project. To the point that I developed a "const pointer" class to wrap all my pointers (only got partially deployed into the project).

D 1.0 lacks const (because it is hard to get right, witness C++). D 2.0 wants const done right.

Also, there is a great slam on Java and const. (I can't help myself when it comes to slams on Java! :) Yea, no const for you Java-kins!

Sunday, October 26, 2008

New Stars Status

I've been struggling with whether to extend the regression, or to get things into shape for a pre-Beta test. I like the regression (being repeatable and all), but it takes as much work as playing the game (more, since I have to play both players).

Of course, shaping things up for a live test requires different sorts of GUI programming...


Here we can see the major changes:
  • I added the icons for two of the planet views (ship view - mostly implemented, and planet value view - next to be implemented)
  • Lots of production queue stuff...
  • Shift and control with Add/Remove (10 and 100 respectively, 1000 together). 889 = 1000 - 100 - 10 - 1
  • Added "End of queue" (add is "add before", so we need end - original Stars uses "add after", oops!)
  • Fixed quirks in selection (previously, I deleted the queue and reconstructed it from the current orders - now the C++ code communicates queue changes and the GUI selectively rebuilds the view)
  • Added a binding to the "q" key
  • Fixed a bug related to pressing "Change" queue button multiple times
Fixes that can't be seen here:
  • Fixed a bug in the max usable factories calculation (population was divided by 1000 instead of 10,000 before multiplying by race factory operation factor)
  • Fixed a typo in the component map for Interspace 10. This caused a Tcl error when opening the Ship Design Wizard for players with that access to that component.
  • Fixed key bindings for '-' and '+' on the numeric keypad (linked to zoom) for Linux. On Windows, <plus> and <minus> catches both versions. On Linux, the keypad keys generate <KP_Add> and <KP_Subtract>. May be an X server thing...
  • Fixed transport amount carrying over between different fleets (and players!). The most confusing thing was - a player could order a load 2500 colonists, save and load another turn, and see that load 2500! Except, the order wasn't given, so they'd launch with no colonists! Ops!
  • Unlinked open file command from "Find" operations (it was intended as a place holder, I find "" makes a better one!)
I'm pretty sure there is a bug in "Remove" multiple, when there are not enough to satisfy the remove (for example, remove 1000 - when there are only 999). The remove will probably remove more stuff, until the count is satisfied! I will fix that...

I also need to implement the hab view.

And fleet split/merge. Fleet numbers. Fleet (friendly and other) and planet list.

Thursday, October 23, 2008

Stuff I've read lately

"The Sovereign Grace of God In Salvation" (John Roden) - Reviewed on my faith blog.

Sunday, October 19, 2008

New Stars Status

BOOM!



Further work on the battle VCR.

First, I ran through this battle in the original Stars, and noticed that the Warmonger Armed Probe should be crossing the board faster. I found that the Warmonger did not have his +.5 move bonus. Fixed.

That gave me a test case for a "FIRE" token in the battle report (missles still not supported).

I also updated the selection logic, so that changing the current event (next and previous buttons) selects the acting token.

Wednesday, October 15, 2008

Stuff I've read lately

"Murder in the Solid State" (Wil McCarthy) - Interesting pun. When you think of "solid state" you think of "state of the art" and "cutting edge". But, in the age of nanotech (full of tiny machines and their moving parts), "solid state" is the failure mode (your tiny machines have jammed)!

This book is a murder mystery. Things go pretty well (very suspenseful) for the most part. Although, the ending was a little confusing and unsatisfying.

Friday, October 10, 2008

Stuff I've read lately

"The Sky Road" (Ken Macleod) - Wikipedia says that this book presents an alternate time-line in the "Stone Canal", "Cassini Division" series. I'm not so sure. It's certainly not obvious. One character, "Ellen May" seemed younger than I remember, but I can't be sure. The "Sheenisov" are still marching across the earth, and the "tinker" society seems a believable precursor to the communes in "Cassini". Overall, ok. I still like "Cassini" the best.

"Why I am So Wise" (Friedrich Nietzsche) - Reviewed on my faith blog.

Saturday, October 04, 2008

Aluminum + 1000 resources

= Space Elevator! (thank you Civ 4). Of course, if you build in in the city with the Iron Works (excellent Texas barbecue results in double resource output!), it's only 500 resources; a good city can do that in ten or eleven years.

I've been following discussions on building a space elevator for some time now. I was surprised to see CNN discussing it!

There are two primary challenges connected with building a space elevator:
  1. The cable (or tether) - Spans 100,000 kilometers from the surface of the earth, up past geosynchronous orbit (the center of mass is at the geosynch point)
    • This cable need not be one single piece. This is a confusion many people have ("We can't build a carbon nanotube that long!!111eleven!").
    • The cable need not be of super materials (100% carbon nanotubes, positronium, etc.) You can make it out of bubble gum, although you'd probably need enough to alter the center of mass of the earth-moon system :)
    • Better materials translate into less mass for the initial tether. That means fewer rockets to get all the materials into space.
    • Once the initial tether is up, the first cargo can be more tether, to increase the capacity of your elevator (and build new ones).
  2. The cars (or climbers)
    • The tether does not move, instead, the cars pull themselves up or down.
    • The climbers are actually the hard problem!
    • They must travel the hundred miles or so into the edge of space, and possibly, the 36,000 km to geosync orbit (especially if they are going to be used to add on to the tether).
    • It is unlikely we will want to carry enough fuel for a 36,000 km journey (at 200 mph, that's about a five day trip - one way).
    • That means we need a means of power distribution to generate power on the ground, and get it to the climbers (most likely lasers and solar panels).
The dangers of the space elevator (terrorist attacks on the base, the tether, or the geosync station) are largely exaggerated. Breaking the tether would cause pieces of it to burn up or fall to earth. It is relatively small, and would do little damage. If the base were destroyed, the tether would slowly rise (there is slight pressure up, to keep the tether tight).

The hazard to lower orbiting satellites is more than offset by the increased launch efficiency. (There would need to be a workforce assigned to pushing satellites out of the way, or a way to shift the tether around them - such a shift might even be useful in dodging meteors or terrorist suicide attacks).

The good news is that the space elevator used to be considered a tech level 9 or 10 achievement. It appears, it will be completed easily within the tech 8 time frame.

Tuesday, September 30, 2008

C-piphany

(rhymes with epiphany)

At some point, I realized why C++ is so unwieldy.

It is really three (or four) different languages:
  1. Macro preprocessing language. #define, #include, etc. Mostly deprecated in C++, except for #include, and #ifndef protection in header files. Except when someone drops 300k lines of 15 year old code on you, and it is filled with all sorts of "horrors man was not meant to know" (TM).

  2. Base C language (and C++ extensions, which can be considered a language unto themselves). What we normally think of as the language, with declarations and operators. I think this is where C++ shines, with lots of tools to wedge things together (operator overloading, references, etc.).

  3. Template programming language. This is needed for the standard library (arrays, etc.). Except, it becomes all to easy to start coding everything in templates. Then, you're hardly using C at all. It's all bizarre template stuff. It's all in header files, and it's all ugly and hard to understand...
Hopefully D fixes this. I know the macro preprocessing is gone (integrated into the language). The D template syntax looks much cleaner.

Monday, September 29, 2008

Stuff I've read lately

"The Stone Canal" (Ken Macleod) - This is the precursor to "The Cassini Division", which I read first. I find it didn't add much, although it was ok.

"Why God Won't Go Away" (Andrew Newberg, Eugene D'Aquili, Vince Rause) - Reviewed on my faith blog.

Monday, September 22, 2008

New Stars Status

Big landmark! The Battle VCR!



It also includes the battle report window (very small, just left of the top of the VCR). This allowed me to find an interesting bug. Scan was comparing pointers, so the same ships were getting scanned over and over.

I also added the detailed scan for ships in battle (still need to make this the behavior for WM scans).

This check-in also includes a top level Tcl XML DOM. That's a complicated way of saying Tcl now has access to the parsed XML file at any point. Previously, it required C++ to parse the XML, and could only query the XML for individual objects. This should allow me to migrate to an all Tcl client (or at least one independent of server code).

Sunday, September 21, 2008

The Horror, the Horror

(Continuing my rant on g++ 4, which is a part of my musings on D)

Ok, take the code from last time, and add this after the "class Par" definition:

template<typename T>
class Child : public Par<T>
{
public:
void fun(void)
{
x_ = 4;
}
};
This code should compile on on gcc 3.4 or in Visual Studio. g++ 4 gives the following error:

main.cpp: In member function 'void Child::fun()':
main.cpp:22: error: 'x_' was not declared in this scope

Err, excuse me! x_ is inherited from the parent. Just look, it's 'int x_'. It's protected, that means it's visible to any children! How can I fix this! I don't know what to do!

After about five minutes of careful Googling, I found a site that seems to understand what's going on. They say:
"The C++ standard prescribes that all names that are not dependent on template parameters are bound to their present definitions when parsing a template function or class."
There is actually a good reason behind this. People were having problems where templates were full of buggy code, but no one knew it until you tried to use them (because the compilers were just turning off error checking when interpreting template code). So now, compilers are trying to understand the template code, and check it for errors. The only problem is good code is now wrongly flagged as erroneous code. Oops!

There is a fix:
this->x_ = 4;

Ok, I can see how that helps the compiler figure stuff out. However, it hurts my brain... If somebody else sees this code (and isn't familiar with this change in the compiler, like say they've been programming C++ for the last ten years and never seen it - like I was until this week) they are going to say, "Oh, that 'this' isn't needed. I'll just remove it." Let's say it's in some utility header (like a good template should be). And that it takes an hour to recompile (like my project does). And they change a lot of other stuff before starting a full recompile (because you don't want to wait an hour between every one line change). And then they get that bizarro error. Yea, they're gonna be mad. And they're going to have to back track through all the changes they've made, google for the page above (assuming they can find it, I only found it by looking for "two stage name lookup" - yea, that's intuitive), and recompile another hour or two.

Enjoy! :..(

Note: apparently, it went into g++ 3.4, only 3.2 is safe!

Saturday, September 20, 2008

c++->fail()

(Continuing my musings on D)
(that code actually works, try (assuming C has a method fail):
C cAry[2];

C *c = cAry;
c++->fail();
)

I got bit by several very ugly bugs in g++ 4 this week. This is about code that works in gcc 3.2, 3.4, and Visual Studio. But breaks in g++ 4.

This is because g++ 4 is more closely matching the C++ spec!

See below for the exact code.

The first problem is mixing implementations of template member functions. This might be because you need to specially handle certain types (like strings), while having a generic implementation for the standard types (int, bool, float, etc.).

The notation in pre g++ 4 is straightforward (if ugly)

returnType ClassName<SpecificType>::functionName(args) { specific implementation }

and

template<args>
returnType ClassName<args>::functionName(args) { generic implementation }


When I compile under g++ 4, I get this error:

main.cpp:16: error: too few template-parameter-lists


In the code below, line 16 is:

void Par<std::string>::fun(void)


Well, there is the template parameter! Right there! "std::string", it's string! What more do you want from me!

Here is the working code:

template<>
void Par<std::string>::fun(void)


Oh! Of course! Duh! I should of known that. The earlier code was obviously so ambiguous that only every compiler before g++ 4 could figure it out. I'm so glad they fixed that for me!

Here is the total code:

#include <cstdio>
#include <string>

template<typename>
class Par
{
protected:
int x_;

public:
Par(void) {}

virtual void fun(void);
};

void Par<std::string>::fun(void)
{
printf("String ver\n");
}

template<typename T>
void Par<T>::fun(void)
{
printf("Generic ver\n");
}

int main(int argc, char **argv)
{
Par<std::string> p1;
p1.fun();

Par<int> p2;
p2.fun();

return 0;
}

Friday, September 19, 2008

Stuff I've read lately

"The Cassini Division" (Ken Macleod) - This is actually the third book in a series. I am really enjoying Macleod. His writing is reminiscent of the "good ole days" of science fiction; with big ideas and epic happenings. And there is a good amount left to be mined here (Cassini is from 1998). Stross is writing too much fantasy (Merchants), and horror (Atrocity Archives). Scalzi has just gotten started.

The Cassini Division is a military unit stationed near Jupiter (and, apparently, a gap in the rings of Saturn). They are charged with protecting Earth (and the orbital settlements) from "post-humans", a group of people who uploaded themselves into computers and set off runaway technological progress (the "singularity").

Macleod has an interesting take on the STL/FTL problem. He uses the "hard" sci-fi notion of wormholes (paired creations, which must be moved apart at STL). However, he also allows that the moving end of the wormhole keeps its own time frame - thus, you can travel 10,000 light years (to a point 10,000 years in the future) fairly soon after the wormhole is created. Interesting stuff.

Thursday, September 18, 2008

Decoys

(Continuing my musings on D)

Garbage collection:
  • Although it's always fun to mock people who fail due to memory leaks while using a garbage collected language...
  • I think D simultaneously defeats C++ and Java/C# here...
  • But, but, C++ has garbage collection libraries! Yea, in ten years of programming I haven't used a C++ garbage collection library. I have used Purify, Valgrind, and even overloading new and delete; looking for memory leaks (not to mention the NewStars code is loaded with memory leaks...)
  • Java has garbage collection, and only garbage collection - unless you use Embedded Java, then you get no garbage collection! Enjoy!
  • D "makes the easy case work". The default is garbage collection, with overrides for self-managed memory (of various forms).
Built-in documentation:
  • Doxygen ('///' and '/***/') works on C++ and Java (it's an extension of JavaDocs)
  • However, it needs to run as a separate step of the build.
  • This can be confusing. For example, I ran the debug build, and didn't see Doxygen (although it might be in there, with make spewing thousands of pages of output...). Some of the code uses it, some doesn't. So, I started converting everything to not use it (it's ugly and confusing, if you're not going to generate the docs). Until I discovered than there is a build that does use it (and the code not using it, needs it)
  • Less ugly Doxygen style comments are built into the D spec. There is a compiler switch to do the docgen run.
Design by Contract (DBC):
  • Programming is all about assumptions. When writing new code, you've got some idea of what's going on in the program, and what the inputs will be, and what sort of outputs you can create.
  • Of course, assumption are made to be broken. That's why I'm always sprinkling my code with plenty of 'asserts'.
  • DBC formalizes all of this. 'assert' is part of the spec (rather than being an ugly macro). Also, there are 'in' and 'out' blocks for functions (to check inputs and outputs). Classes have 'invariant' statements, which are processed before and after functions (to ensure class invariants are maintained).

Wednesday, September 17, 2008

Duck Hunt

(Continuing my thought process for considering a new language)

Nine to five, I hack C++. Not just any C++. Imagine hundreds of thousands of lines of code, spread across dozens of directories in a twisty maze. Make takes from twenty to thirty minutes (that's a parallel make, serial is over an hour), and sometimes fails in odd ways.

The program has to run on about five different compiler/platform environments (Windows, plus various forms of UNIX - including a Sparc).

Over the past few weeks, I've been running into all sorts of nasty C++ problems (weird template problems, compiler mismatches, spaghetti recompilation).

As I've been looking for solutions to the problems on the Internet, the C++ Frequently Questioned Answers keeps coming up.

The guy makes a lot of good points. And I started to wonder, does he have some constructive recommendation (besides, "Don't use C++").

It's called D.

I think, what I'm looking for isn't Python or Ruby to replace Tcl. I need something to replace C++. With features like Python or Ruby (rapid development, functional programming).

That's D.

Things are still a little fresh (spec is rapidly moving, environment issues). But considering that, it is working remarkably well. I mean, C++ is way older, and still has issues!

A good place to start is with the overview.

Tuesday, September 16, 2008

New Stars Status

Finally getting to the point where I can start on the battle VCR!



It took a lot of bug fixes to get to this point...
  • Implemented ship to ship scanning
  • Fixed bug causing battle messages between fleets the player owns
  • Fixed a bug where planets could not see enemy ships in orbit
  • Added a speed spinner to fleet move orders
  • Fixed a bug when right-clicking on mixed friendly and enemy fleets in one point
  • Fixed a bug where some fleet GUI items would appear in view planet mode
  • Fixed widths of some widgets to fix jumpy universe view size
  • Added previous and next buttons to the message pane
  • Removed ship object id from ship names (just in fleet)
  • Improvements to the scripting interface
The JOAT player is pretty well into colonizing a second planet. The War monger has no orders beyond scanning...

The battle was really anti-climatic. The current battle engine has the JOAT scout escape without a shot fired. I will need to investigate that outcome...

Friday, September 12, 2008

Need a New Duck

And show me how to get down
How to get down baby
Get it?!

Quack, Quack, Quack!
I've probably forgotten more about programming languages than most people know (since most people know zero programming! :)

Basic, Pascal, Visual Basic, C, C++, Perl, Verilog, Java, various assembly languages (including PipeWrench, don't ask), Awk, Tcl, Lex, Yacc, ML (which we all thought stood for "My Language"), VHDL.

At this point, I've pretty much settled on C++ and Tcl. (plus Perl for text processing).

Tcl is great for rapid development, and GUI design.

C++ is great for interface definition, large projects, and general hacking. I don't know Bjarne's background, but it must include a lot of hacking.

But I've been getting the feeling I need a new language.

I tried Ruby. But "everything is an object" doesn't seem any better than "everything is a string" (Tcl).

I've played with Python, but again, it doesn't really replace Tcl for me.

I've used Darcs, which is the poster child of Haskell. That's pretty much turned me off that... The other functional languages are even more obscure.

Erlang seems to have potential for the multicore future. But it seems to be different in annoying ways, "just cause".

Tuesday, September 09, 2008

Stuff I've read lately

"The Birth of Christianity" (John Dominic Crossan) - Reviewed on my faith blog.

"Patriots" (David Drake) - Not your typical Drake. Ok, but more character focused. He should stick to tanks and such :)

Saturday, August 30, 2008

New Stars Status

Trying to work up to a battle in the two player game. I am trying to actually walk the players through their turns as they would be doing them (i.e. spending a lot of time micro-managing).

Part of that is implementing the "accelerated BBS" option (so I don't have to generate 30 turns before reaching colonization pop).

Then, I added the research tax option (visible in the dialog below). This uncovered several bugs in communicating this information from the player file to the server.



I also fixed the scanner pane so that it resizes itself to fill up the window. There is a somewhat annoying flicker as you click from explored to unexplored planets (due to different widths on the left)...

I also found/fixed a bug for JOAT w/o IFE getting Quick Jump 5 instead of Long Hump 6 (IFE properly gives the Fuel Mizer).

As well as a bug in the growth formula when planets exceed 25% capacity (aided by AccBBS).

Interesting note, on Linux, the two players are right next to each other. That means I can use it for some quick battles (and I need to fix the homeworld placement logic...)

Wednesday, August 13, 2008

Stuff I've read lately

"Dark Light" (Ken Macleod) - Sequel to "Cosmonaut Keep". Very short, but pretty good. Follows the adventures of the previous characters on a planet some light years from the last (they got their light drive working). The libraries here don't have the third book...

"In My Place Condemned He Stood" (J. I. Packer and Mark Dever) - Reviewed on my faith blog.

Tuesday, August 12, 2008

New Stars Status

Started in on more bugs:




Here we can see the new universe caused by fixing the randomization of the hab distributions. I also added the player relation dialog, and changed the underlying implementation. With those changes done, I can revamp the battle engine - in preparation for the battle VCR.

I also fixed some of the automation, to improve fuel consumption during scouting missions.

I looked into the fails during generation huge universe (dense and packed). They are running out of planet names. We will need to generate another 1k names...