Of year 2002
Main LTGameJam page here

Development thoughts

2002 08 17

I've gone through the not-so-easy task of documenting the engine! Doxygen gave me a pile of html's; also I've drawn some UML (the rest is still todo).

The engine seems to be nearly completed. There are some missing things, but we could keep adding them for ages - there's always something missing :) So, I'm marking it as "Release Candidate 1".

2002 08 13

Time to merge my (NeARAZ) and ReJ's code... We couldn't easily agree on some things, so we tried all the combinations :) It's clear that his entity renderer is better; but we're still in doubt about his vs. mine entity system...

2002 08 12

Almost accidentaly I've written a game! It's an extended version of the "Rail game", this time with peaceful and angry gods also :) See it in development files.

The system of entities and user interaction is now the "indirect one" (see somewhere below). It has proved to be faster and fairly comfortable to use.

Shuffled the source files layout, the game classes, etc. Started writing source comments, tried Doxygen - it works :)

2002 08 10

Game idea: Babel tower game (by Aiste). There are different colored people running round on the map. Colors represent the language they speak. You select rectangles (or circles, etc.) of them to combine them into one. If among the selected ones are 70% (or 80%, 90%, etc.) of the same color, then you succeed and they turn into a big "unit" (or man) of the major color. If you fail, something bad happens. The task is to combine some not-so-small amount of single colored people to finally build the tower.

Two cases for interaction with entities:

  1. The traditional one. There's a world space partition into sectors (simple case may be ok: fixed 2D grid). Each entity knows the sector it belongs to, and each sector knows the entities it contains. This approach is simple to understand and implement, and suites well for (nearly) all kinds of problems (collision, proximity queries, selecting entities, etc.).
  2. The indirect one. Again, there are sectors. The difference is: the sectors know nothing about the entities, and the entities do not track the sectors they belong to. The sectors are just containers for some data that is used for entities interaction. Consider a case of ray-entity intersection: each sector has a ray (or hasn't). At first we write a ray into the sectors it crosses (and don't write into the other ones). Then each entity computes the sector it is in, checks whether the sector contains a ray, and if so, checks itself against collision with ray.
The second approach is slightly harder to understand, and it moves all logic into the entity. But is has some advantages: no need to track entities-sectors relations. I've written a "Rail Game" using both approaches, and the second one turned out to be faster (50k entities, AthlonXP 1500+, 256 MB DDR RAM, GeForce2GTS: 46 vs. 50 FPS).

2002 08 08

ReJ was trying various ways (and hacks also :)) to speed up the rendering. At first I did the rendering as such:

  1. Lock whole dynamic VB with DISCARD flag (size of VB is 16k vertices).
  2. Fill it with sprites.
  3. Unlock.
  4. Draw.
  5. Repeat until no sprites left.
ReJ optimized off some branches (no sprites left? whole VB filled?) and "split" filling of VB into portions (fills smaller portions with NOOVERWRITE). This is (AFAIK) the current scheme.

Also we noted a couple of interesting things: filling the VB, but leaving some parts untouched (like texture coordinates in NOOVERWRITE portion) does not speed up things at all. Knowing we're RAM limited, it's kind of strange. Maybe it's some of AGP specifics?

CPUs and FPUs nowadays are too hard to understand. We have 5 vector3-scalar multiplications in one sprite. Commenting out the first one speeds up calculations by 50%. Commenting out the just the last 4 (leaving the first one) speeds also by 50%. Commenting out one of the last 4 does not speed up things, and occasionally slows them down. Also: inserting redundant code (that isn't executed at all) sometimes speeds up things. "The pipelines and superscalar things are roots of all evil" - the conclusion :)

I (NeARAZ) have coded up a "Rail Game". See it in development files. For that game there's a division of playing space into sectors, each entity knows the sector it belongs to, and sectors manage pointers to entities they contain. With this structure, I'm able to find intersection of some ray and entities (and also do collision, proximity queries, etc. etc. - not done yet).

2002 08 05

Dilemma: should we try to hide the engine from the programmer, or should we expose it? Exposure is good for such a project, but we fear that the programmers would dig into the engine instead of writing games :)

Just to check: physics for each entity can now hold it on the terrain all the time, let it fly or let it fall with gravity. I've spotted no difference in speed. So: we're pretty ok with branches in the code. We're not ok with RAM :)

So, what I would do:

  • There's common physics code for all entities, using bit flags in entity structure for various physics parameters. Just like everyone did some years ago.
  • Each entity has a pointer to current "decider" (or null). Decider gets called not too often (or: quite rarely). Deciders could be possibly shared by entities; they would have interface like virtual void decideFor( SEntity& e ) const; The game does like this: creates a decider of it's will, sets it for some needed entities, sets it's calling period, and voila! The ability to report something can be left to the decider (like: some entity reached the destination!). It's game's responsibility to delete/destruct the decider (afterall, the game is the one who creates them). So, generally the decider is the AI for an entity.

Game setup scenario:

  1. Create, say, 7 entities, set "bad guy" decider for them. Have pointers to the entities (or deciders) in "bad guys" array. Bad guys run in circles around the map, inflicting damage ("dropping" it onto the grid beneath them). One can also implement collision detection & response between bad guys...
  2. Create, say, 50k entities, set "good wandering guy" decider for them (that randomizes the velocity every now & then, possibly turning away from the bad guys; and accepts damage from the underlying grid).
  3. In result we get a game with many guys wandering around, and a few bad guys running and killing good guys. Interesting game, isn't it?

A dilemma to resolve: should we have (stochastic) collision detection? Or will the "underlying grid" system be enough? In the latter case: should the sectors know which entities they contain now (and so for the entities)? The knowledge introduces some overhead, on the other hand, it has it's own advantages...

2002 08 04

Checked out IndieGameJam sourcecode. It was similar to what we would do - pool of entities, single big texture, space subdivided into sectors, etc. What we haven't thought of is the idea of game updates affecting only a subset of entities (thus bypassing the main bottleneck - RAM throughput). It seems to be a good solution.

On the other hand, I was a bit suprised. They use plain C nearly everywhere, using "// don't modify this!" for encapsulation, callbacks and other good old C stuff. While I don't generally agree with ReJ's code also - it's OOP too much (relatively). What I think we can allow is: we're pretty ok with C++, but don't really need the inheritance or polymorphism for the game entities. Let's remember old times...

The vision I see now is:

  • The entity is a fixed size data structure, with some space reserved for game needs. Method update() handles a single guy (updates it's position, checks terrain altitude, etc.) and should not be modified by game in most cases.
  • Game logic is happening either in Entity::gameUpdate() for some of the entities (equiv. of ai_timer in IndieGameJam), collision managers or Game::internalUpdate().
  • Collision is stochastic (only a subset of sectors gets evaluated each update).
The whole design very resembles the original IndieGameJam... Well, not too much of a surprise, anyway :)

Specially for ProNinja: maybe we'll have a collision detection! (as it was said, stochastic only).

Code, code, code... The codind is not as fast as it used to be 2-3 years ago. I think a lot more (what's the better way? how it will integrate into the whole thing? etc.). Is it good or bad?

2002 08 03

With 100k entities you very quickly reach system RAM throughput limit. CPU limit comes the next, and GPU the last. 100k sprites == 400k vertices, that's "a breeze for GeForce" (needs to be read in female voice), as said in one old nVidia demo movie.

But even the CPU limit is not so high: if we process every entity at 10Hz rate, and let us "burn" something like 500MHz (leaving other for rendering, driver, Windows, etc.) - that's 500 cloks per entity. Kind of low...

Something has to be done. Process entities in groups? Cache something (like colidees, paths, etc.) by location? Or have 10k entities... or 5k...

older ones

Some game ideas:

  • University game (by ReJ). There are "good" students (those that pay for the studies) and "bad" - the ones that don't have to pay. The task is to keep as much of the good ones as possible, or convert bad ones into good ones. But you must also leave some bad ones (but the ones who have the highest marks) untouched. Also the periodic floods (yearly) of students, the army and more stuff can be introduced.
  • Politics game (by Aiste). You are a politician, and can promise some things to the people. First you must gather some audience to promise to, and then select the thing. Some people that don't like the thing die immediately, the ones around them run in panic, and the others stay as your supporters. With network, it can be a fight between more politicians.
  • Runnin' troops (by NeARAZ). You drag short strokes on a terrain, and there appears a bunch of troops and start running in the direction of a stroke. While running, it destroys everything in it's way, digs the terrain, etc. One bunch destroys the enemy bunch if it runs into it's side. Errmm... and something else.
  • Mosquito game (the idea came out naturally, while camping). Hordes of moquitos attack people, people defend by smoke, sprays, pshychological attacks :) and so on.

Site typed in by NeARAZ, 2002.