Tuesday 25 November 2014

London Game Craft

On the 29th of November, Songbird Creations will be attending the London GameCraft Jam at The Skills Matter eXchange.


We won't be working on a game however we will be providing green-screen and image processing facilities for the developers there so they can quickly get some nice real-life graphics made without worrying about it. We'll be taking care of the capture, chromakey and processing - the end result being a nice texture file and plist using texture packer.

We'll be bringing some props with us although, the theme for the day hasn't been announced - so that'll be interesting.


So if you're attending the Jam, pop over and say Hi. I'll probably be decked out in a green-screen suit, so I'll be invisible.... :-)

https://skillsmatter.com/conferences/6610-london-gamecraft-2014-part-trois

Sunday 5 October 2014

Review the Ancients: Slightly Magic 1991 - Codemasters - 2014 Potassium Frog

Slightly Magic

Written in 1991
Coded by Colin Jones
Graphics: Chris Graham, Colin Jones, Keith Ross
Music: Allister Brimble
Published by CodeMasters

Re-released 2014 by Potassium Frog
Available for PC, Linux, Mac, Android, iOS and OUYA
http://slightlymagic.uk/


I remember this game being fairly tricky.

There were quite a few platform adventure games during the Spectrum's life, Dizzy being one of the most famous (at the time). The idea of a non-combat adventure where you solve puzzles without resorting to violence struck a chord with me, and still does to this day.

With Dizzy you ran around solving puzzles with inventory items while avoiding enemies with running and jumping - a task made more difficult by Dizzy's tendency to roll around.

Slightly Different

Slightly magic was a little different in this regard. Instead of controlling a rolling egg, you controlled a young wizard - complete with wizard's robes and hat; and instead of purely needing the right object at the right time, in Slightly Magic you have use an item with a spell to make the spell work as well as have your spellbook and magic wand. The spells can be used many times and do various things from make ghosts fly away to change your shape; There's even a spell to give a giant an itchy head.
Spells use magical energy which you obtain from stars you collect.
It was a nice and refreshing addition to the regular inventory mechanic which opened up new elements of gameplay.

The main character of the game is a young magician named Slightly. Slightly's Uncle, the wizard Bigwiz has left the castle in a hurry and has forgotten a whole load of things in his haste, one of these things being to take his nephew with him. He also forgot to lock the door to the laboratory and the spell cabinet has been knocked over  sending the spells everywhere. All this coupled with the fact that a sunburned dragon has made off with Princess Croak, it's up to Slightly to fix everything.

Slightly Unusual

I typically review old games which struck a chord with me in some way while I was growing up.
They are normally obscure titles which deserve looking into and will often need the reader to dig around for them. They are the ancient games I grew up with and are not generally available for purchase.

This review will be a little different in that Colin Jones has re-released Slightly Magic on tablets and the OUYA. This review will focus on the OUYA version - mostly to support Colin Jones and the OUYA and in some small way because it's very difficult to get hold of CodeMasters games on-line to play due to CodeMaster's legal block on them.

Thankfully Colin has been able to re-release the game so that future generations can play it and to prevent it from being lost to obscurity. I sincerely hope other CodeMasters games share similar good fortune otherwise they will fade from memory altogether.

This good fortune does present a problem for me though.
Given that the game has been re-released, I am torn whether to review the game from a modern perspective or against its peers of the time - after all, I gave Treasure Island Dizzy a glowing review in spite of the fact that it would probably be responsible for the destruction of TVs through controller impalement.

However given that Slightly Magic is available for purchase and it's peers are contemporary, perhaps a purely nostalgia based review might not be right. I will however review it as fairly as possible.

Slightly Singed

You start the game looking at the young wizard, on the screen you can see a spell book and a magic wand (also belonging to Bigwiz the wizard and also forgotten). The magic wand is in a corner of the screen blocked off with walls. To get the wand you're going to have to work out the way to that part of the castle.. but first of all, you have to get past some dragons.

The dragons burn you if you get too close, not deliberately mind you, they are thirsty and are breathing fire so they need some water to put out the flames. The problem is that they'll only drink from their own buckets. They're the King's dragons so they're picky like that.

This leads me to the first issue I have with the game. It's difficult to know what will kill you and what won't without experimentation and that can be dangerous - also with your lives being limited, you'll be replaying some bits of the game over and over. Not as fury inducing as Treasure Island Dizzy though.

Once you've worked out the solutions to puzzles, you'll optimize your path in no time. This type of gameplay was commonplace back in the 80's and 90's but not really seen any more.

Whether it causes more frustration now than it did back when I was a kid I'm not sure. What I am sure about though is that modern games have removed these gameplay elements for better or for worse and no-one is complaining.

The game appears to rely on the player making mistakes to learn where some off screen platforms will be. Some platforms require the player to jump from one platform on one screen to land on a platform on the next as there is a gap immediately which would cause the player to fall should they just walk off-screen.

However, all of these points are due to the fact that this game is a remake of a 20 year old game so we're going to cut it a reasonable amount of slack. It would have been tempting I'm sure to alter the game in small ways but this could have lead to the loss of the soul of the original - something which thankfully the game has kept.

There is no save system in the game to record your progress.
Once you run out of lives you'll have to restart the game. This is perhaps fair, however should you find yourself running out of time to play, you cannot save the game and come back to it.
This is a real throwback to the original time when saving was more trouble than it was worth however I'm not sure that modern gamers will be able to overlook this.

I feel that this would have been something that could have been implemented behind the scenes, saving progress as the player went along and allowing the player to reload the game state or choose a new game.

Oddly enough in it's defence, the game is quite short and can be completed in about 20 minutes if you know what you're doing.

Slightly Blocky


The graphics are charming and cute, taken pretty much directly from the ZX Spectrum version. This is as close as you're ever going to get to the original Pixel-Art style. Every pixel on the spectrum had to be crafted with care.

It all still works. The graphics are crisp and clear with nice chunky pixels. The remake also doesn't need to worry about the Spectrum's limited number of colours per block of 8 pixels so there's no annoying colour clashing going on.

Whether new potential fans will appreciate the style or be put off by it remains to be seen. I'm pretty sure the discussion was had to upgrade the graphics or not when this project was first floated.

Personally, I like the graphics. As a child from the Spectrum years, they are familiar and look different enough to stand apart from the competition.

Pretty much everything in the game is animated to some extent. From a bouncing glittering spellbook to spooky ghosts. Even the user interface has a bubbling bottle of some magical liquid showing your lives and there's a really cute bouncing star showing the number of stars you have collected.

The game screams cuteness.

Slightly Musical

A jolly tune played throughout Slightly Magic on the 128k Spectrum version and of course on the Amiga version. It matched the tone of the game well feeling like it belonged as the title for a 90's Saturday morning cartoon.

The remake doesn't stick with the spectrum version of the soundtrack. It appears to be taken from the Commodore Amiga version - which as a fan of the original was a little jarring especially with the Spectrum graphics. The tune is basically the same but there are differences.

All those hours from my childhood had burned the theme-tune into my brain (and I do have a great memory for music - if little else) and I do find the 128 Spectrum's sound particularly pleasing.

The newer sound-track is certainly richer and changes song as you visit different areas which is a nice touch. From the jolly tune in the castle to a spookier version to go with the forest outside. What's nice is that it keeps the main melody.

Here are the two soundtracks to play and compare - however they are both walk-through videos so be aware that they will contain solutions to puzzles and spoilers. Viewer discretion is advised.



Slightly Surprised.

Since buying the game for the OUYA I learned that Slightly Magic was the subject of a kickstarter campaign to bring the game back to life for tablets and the OUYA - unfortunately it did not meet its funding goal which is a real shame.

One of the features should it have been successful was to have Allister Brimble re-record the soundtrack with all new and modern technology. I can only imagine what that would be like, but I can imagine it would sound very nice.

The failure of the kickstarter to meet it's goals means that Colin did not receive any money to get this game re-released so I can only guess that he funded the game himself.

The original game when released perhaps had an easier time at defeating it's competition - it certainly gave the Dizzy games a run for their money and received rave reviews from the press at the time.

One thing is for sure, there is a tremendous amount of love to the game. There's not an ounce of bad will in the game or the story. In fact, the only malicious character in the whole game is a witch with a cottage in the forest who has turned Hansel and Gretel into gingerbread people - another thing for Slightly to put right.

The fact that the kickstarter failed and yet Colin still proceeded to make the game is a testament to how much love he has for the game.

In Closing

The graphics are a pleasant throwback to a more innocent time but may not win over newer fans who could dismiss them too easily - which would be a shame. Personally I think they look different to anything else on the OUYA which helps it to stand out.

The music could probably use some higher fidelity samples but is pleasant enough. It still has that jolly feel to it. A modern Allistair Brimble soundtrack would have been amazing.

The controls could use re-mapping. There were many times where I pressed [O] to access my inventory, for something to happen and pressed [O] again to close the message - which did nothing, [A] closes messages. I'd have them both do the same action and have [A] for jumping.

The lack of a save option I feel will put people off, even though the game is short by modern standards, the mobile gaming audience often have limited time to spend playing. So a save as you go feature would really help.

The game's mood is very nice and the screens for each area demand to be explored.

It has more character and charm than a lot of more modern games and was obviously a labour of love.

Thank you Colin Jones for this trip to my childhood and for bringing Slightly back for future generations to enjoy.











Monday 29 September 2014

Review the Ancients: Treasure Island Dizzy - CodeMasters 1988

Treasure Island Dizzy

Written in 1988
Coded by The Oliver Twins
Graphics: Neil Adamson
Music: David Whittaker
Published by CodeMasters

http://www.worldofspectrum.org/infoseekid.cgi?id=0009333
Play it online http://torinak.com/qaop#!dizzy2

The Egg Who Returned

Back in 1988 we saw the return of The Egg who wears boxing gloves. Dizzy.
His initial game came out the year before but Treasure Island Dizzy turned everything up to 11.
It had a proper masked sprite system as opposed to the XOR rendering of the original and it had a 128k soundtrack by the ever wonderful David Whittaker. He included a 48k soundtrack for those with older spectrums but the 128k version was the best by far. It also gave us in-game music. Music who's pleasant jaunty tones concealed any malevolence within.



Treasure Island Dizzy was much in the same vein as it's predecessor, a flip screen adventure game with inventory puzzles and platforming. Very simple game-play. Move, Jump and collect/use.

There were changes though.

Original Dizzy only allowed the player to carry a single item, which must be dropped should the player want another item whereas Treasure Island Dizzy allowed for three items.. a design decision which would alter the gameplay and difficulty in ways they probably didn't foresee (..or did they?).

Another decision they took was to remove the lives system used in the original whereas the player had 3 lives to start with but could collect more as the player progressed. This was removed and was replaced with Permadeath.

They also removed the random flying enemies (see God Damned Bats trope ) from the original and replaced them with enemies which followed a specific and predictable path - if they moved at all. This made things a little easier. a little.

Treasure Island Dizzy is very hard.

I mean seriously really very hard. Don't underestimate this game.
Kids today are not prepared for how soul crushingly hard this game is. Seriously!

It's not hard in a dark souls way where you have to memorize attack patterns and weaknesses to succeed - no, Treasure Island Dizzy is harder than that. You see, in Dark Souls, should you die (and you will.. a lot) you don't have to start from the beginning again.

With Treasure Island Dizzy, should you make any mistake - like fail to avoid one of the few traps, get hit by a creature, burned by fire, fall in water without a snorkel, or drop your snorkel while underwater while trying to pick up another item - Then it's back to the start of the game.

No matter how far you have progressed.

And it wasn't a small game either. Here is the map for your viewing pleasure:


As you can see, there are items to collect, hidden coins which you need and the same puzzles to solve over and over and over again.

It sounds terrible right? So why does this game invoke such fond memories with it's players?

Well, for me it was initially the cuteness of the thing. The happy egg waving along with the jaunty tune, jumping and rolling. Dizzy was innocent. He was happy. Every time Dizzy died and I had to restart the game from scratch, it was my fault. Each and every time. There were no random actions, no traps that couldn't be avoided. With each death was a failure - My Failure.

I don't like to fail so I persevered. I learned where items were. I made sure that my snorkel was always the most recent item in my inventory so that when I picked up an item under the water, I wouldn't drown.

I timed the jumps, the rolls and even memorized the most optimal route through the story to get things done.

After a lot of work, trial and error and a home made map, I finally got to the end screen.
I had collected all 30 of the coins (some were hidden in evil places)  and I completed the game.

I DID IT!

To be greeted by a message.

CONGRATULATIONS! You have successfully solved all the puzzles and truely earned your freedom. Good luck Dizzy.

I nearly had a psychotic breakdown.. after all of the work and retries the game was over with a simple message - then it was right back to the title screen again.

"Welcome to Treasure Island Dizzy!"

I sat in shocked silence watching the title screen for several seconds before I calmly put the tape back in its box and reset the computer.

I never tried to complete it again. That was it.. I was done.

But did I have fun? Yes. Absolutely. The feeling of solving a seemingly difficult problem and making progress was amazing. Making the jump to land on the top of the mine, jumping the crab and drowning the Sinclair Abuser magazine.

Collecting some items and solving puzzles opened up new and interesting areas which really helped to sell the mystery of the island. Because there were no enemies trying to kill you generally, you were free to explore - just be careful.


In modern terms, 

I do wonder whether it would be more fun if the permadeath was removed. Would the game still be fun if instead of a "Restart from the beginning" or "several lives" approach that a restart from a checkpoint system would be better. It would certainly be more forgiving.

However restart-checkpoints didn't really come into existence until Sonic the Hedgehog and even Sonic had lives.

This was the 80's/early 90's we had what we had and we had Dizzy and that was alright.

Finally

I would recommend that anyone interested in game design and gameplay gives this little old gem a shot. It's got a lot of heart and is worth the time. Whether you want to devote enough time to complete the game will depend on several factors, one of which being your sanity.

If anyone complains about how hard a modern game is, if you've played Treasure Island Dizzy, you can scoff at their ineptitude. Pah! You don't know hard until you've played Treasure Island Dizzy!


I've placed a link at the top of the review so you can play it on-line. CodeMasters have not yet given permissions to reproduce any of their games online which is a shame because they'll be lost in time in a few years unless they're allowed to hosted by fans.


For my mind, The Oliver Twins made the games which made CodeMasters a household name.
I owned a great number of their games and enjoyed them all. They still make games as Blitz Games Studios - They have a simply staggering collection of titles to their name. To call them prolific would be an understatement.

Gentlemen, I salute you!




Sunday 28 September 2014

Box2D Raycasting with Category Masking with MOAI

What is Ray Casting?

Ray Casting is a technique used to determine whether something intersects a line drawn between one point and another. Normally Box2D uses circles, rectangles and polygons to determine collisions and resolve the forces and positions appropriately. However sometimes you just want to check for collisions along an imaginary line.

Imagine a Laser Pointer

One example for this is if you imagine a laser pointer.
Its beam is emitted from the end of the laser pen and it continues until it hits the wall at the far end of the room and leaves a pleasant red dot.

Should something break the beam, the red dot shows on the object breaking the beam and no longer on the wall.

Before MOAI 1.5

For a long time, MOAI did not support the ray casting features of Box 2D. Version 1.5 supports the closest raycast implementation where the closest object on the path of the ray is returned.

The Closest raycast feature is very much like the laser pen example. A ray is cast and the first thing which intersects the ray is returned.

A lot of the time, this is all you need.

It will find the closest Box2D fixture intersecting the ray no matter what it is.

Category Masking?

I needed something a little extra. Box2D supports categories. This is so you can designate an object as a particular type of thing so it can be included or excluded in specific collisions.

For my game I have several categories for objects.

  • FLOOR = 1
  • PLAYER = 2
  • OBJECT = 4
  • MONSTER =8
  • SWITCH = 16
  • POWERUP = 32

My laser beams should only be stopped by Players, Monsters and the Floor. Objects, Powerups and Switches should not get in the way - let alone be blown up by lasers.

I need a mask to filter only the categories I'm interested in.
FLOOR + PLAYER + MONSTER = 11

By performing a bitwise AND against the category for the object intersecting the ray and the mask, we can check to see if we're interested in it.

Here's a little binary refresher so you can see why the mask works.

Floor   = 00000001
Mask    = 00001011
Yup

Player  = 00000010
Mask    = 00001011
Yarp

Monster = 00001000
Mask    = 00001011
Yessir

Switch  = 00010000
Mask    = 00001011
Nope

However... 

Box2D doesn't support category masking for RayCasts, even though it supports categories and masks for all other types of collision detection.

This meant that even with the implementation in MOAI release 5, I couldn't use the Box2D ray casting. In fact, it meant I couldn't use Box2D* at all without making some changes.

*I'm using Box2D v 2.2.1 within MOAI - the most recent appears to be 2.3.0 (as of time of writing) however it too does not support masking.

So I modified Box2D to suit.

UDiff for Box2D 2.2.1


 3rdparty/box2d-2.2.1/Box2D/Collision/b2Collision.h     |  1 +
 3rdparty/box2d-2.2.1/Box2D/Collision/b2DynamicTree.h   |  1 +
 3rdparty/box2d-2.2.1/Box2D/Dynamics/b2World.cpp        | 18 ++++++++++++++++--
 3rdparty/box2d-2.2.1/Box2D/Dynamics/b2World.h          |  3 +++
 3rdparty/box2d-2.2.1/Box2D/Dynamics/b2WorldCallbacks.h |  2 +-
 5 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/3rdparty/box2d-2.2.1/Box2D/Collision/b2Collision.h b/3rdparty/box2d-2.2.1/Box2D/Collision/b2Collision.h
index 8bb316c..62c7ee8 100644
--- a/3rdparty/box2d-2.2.1/Box2D/Collision/b2Collision.h
+++ b/3rdparty/box2d-2.2.1/Box2D/Collision/b2Collision.h
@@ -147,6 +147,7 @@ struct b2RayCastInput
 {
  b2Vec2 p1, p2;
  float32 maxFraction;
+ uint16 maskBits;
 };

 /// Ray-cast output data. The ray hits at p1 + fraction * (p2 - p1), where p1 and p2
diff --git a/3rdparty/box2d-2.2.1/Box2D/Collision/b2DynamicTree.h b/3rdparty/box2d-2.2.1/Box2D/Collision/b2DynamicTree.h
index 0787785..ed4afce 100644
--- a/3rdparty/box2d-2.2.1/Box2D/Collision/b2DynamicTree.h
+++ b/3rdparty/box2d-2.2.1/Box2D/Collision/b2DynamicTree.h
@@ -254,6 +254,7 @@ inline void b2DynamicTree::RayCast(T* callback, const b2RayCastInput& input) con
  b2RayCastInput subInput;
  subInput.p1 = input.p1;
  subInput.p2 = input.p2;
+ subInput.maskBits = input.maskBits;
  subInput.maxFraction = maxFraction;

  float32 value = callback->RayCastCallback(subInput, nodeId);
diff --git a/3rdparty/box2d-2.2.1/Box2D/Dynamics/b2World.cpp b/3rdparty/box2d-2.2.1/Box2D/Dynamics/b2World.cpp
index d77e80a..b3497e1 100644
--- a/3rdparty/box2d-2.2.1/Box2D/Dynamics/b2World.cpp
+++ b/3rdparty/box2d-2.2.1/Box2D/Dynamics/b2World.cpp
@@ -1013,7 +1013,7 @@ struct b2WorldRayCastWrapper
  {
  float32 fraction = output.fraction;
  b2Vec2 point = (1.0f - fraction) * input.p1 + fraction * input.p2;
- return callback->ReportFixture(fixture, point, output.normal, fraction);
+ return callback->ReportFixture(fixture, point, output.normal, fraction, input.maskBits);
  }

  return input.maxFraction;
@@ -1023,7 +1023,7 @@ struct b2WorldRayCastWrapper
  b2RayCastCallback* callback;
 };

-void b2World::RayCast(b2RayCastCallback* callback, const b2Vec2& point1, const b2Vec2& point2) const
+void b2World::RayCast(b2RayCastCallback* callback, const b2Vec2& point1, const b2Vec2& point2 ) const
 {
  b2WorldRayCastWrapper wrapper;
  wrapper.broadPhase = &m_contactManager.m_broadPhase;
@@ -1032,6 +1032,20 @@ void b2World::RayCast(b2RayCastCallback* callback, const b2Vec2& point1, const b
  input.maxFraction = 1.0f;
  input.p1 = point1;
  input.p2 = point2;
+ input.maskBits = 0;
+ m_contactManager.m_broadPhase.RayCast(&wrapper, input);
+}
+
+void b2World::RayCast2(b2RayCastCallback* callback, const b2Vec2& point1, const b2Vec2& point2, const uint16 maskBits ) const
+{
+ b2WorldRayCastWrapper wrapper;
+ wrapper.broadPhase = &m_contactManager.m_broadPhase;
+ wrapper.callback = callback;
+ b2RayCastInput input;
+ input.maxFraction = 1.0f;
+ input.p1 = point1;
+ input.p2 = point2;
+ input.maskBits = maskBits;
  m_contactManager.m_broadPhase.RayCast(&wrapper, input);
 }

diff --git a/3rdparty/box2d-2.2.1/Box2D/Dynamics/b2World.h b/3rdparty/box2d-2.2.1/Box2D/Dynamics/b2World.h
index 965a366..d910e23 100644
--- a/3rdparty/box2d-2.2.1/Box2D/Dynamics/b2World.h
+++ b/3rdparty/box2d-2.2.1/Box2D/Dynamics/b2World.h
@@ -121,6 +121,9 @@ public:
  /// @param point2 the ray ending point
  void RayCast(b2RayCastCallback* callback, const b2Vec2& point1, const b2Vec2& point2) const;

+ void RayCast2(b2RayCastCallback* callback, const b2Vec2& point1, const b2Vec2& point2, const uint16 maskBits ) const;
+
+
  /// Get the world body list. With the returned body, use b2Body::GetNext to get
  /// the next body in the world list. A NULL body indicates the end of the list.
  /// @return the head of the world body list.
diff --git a/3rdparty/box2d-2.2.1/Box2D/Dynamics/b2WorldCallbacks.h b/3rdparty/box2d-2.2.1/Box2D/Dynamics/b2WorldCallbacks.h
index 82ffc02..a485d8c 100644
--- a/3rdparty/box2d-2.2.1/Box2D/Dynamics/b2WorldCallbacks.h
+++ b/3rdparty/box2d-2.2.1/Box2D/Dynamics/b2WorldCallbacks.h
@@ -149,7 +149,7 @@ public:
  /// @return -1 to filter, 0 to terminate, fraction to clip the ray for
  /// closest hit, 1 to continue
  virtual float32 ReportFixture( b2Fixture* fixture, const b2Vec2& point,
- const b2Vec2& normal, float32 fraction) = 0;
+ const b2Vec2& normal, float32 fraction, uint16 maskBits) = 0;
 };

 #endif


As you can see, the changes merely extend Box2D's raycast feature to include a request for a specific set of maskBits.  Box2D doesn't perform any filtering internally with this change.

Category checking against the mask will be done within MOAI's implementation coming up next.

Note also that I create a function called RayCast2 which can be called with the maskBits parameter. This is just in case the Original RayCast function is used internally by Box2D and to ensure that other programs using it won't be broken by this change.


Initially it felt like overkill to modify Box2D to just pass a number through and back again. However this is required because the raycast function uses a callback to notify the program that it found something - this callback doesn't have any context as to how it's being called really to know what type of fixture you're looking for.

So apart from hard coding it to ignore sensor type fixtures, you're stuck just returning the closest object of any category unless you pass the mask through to the callback function.

Basically, Box2D doesn't know to inform the callback function that you're really only interested in UFOs and it can ignore Clouds.

Here's the UDiff for the MOAI code 

(Note patch is for 1.4r2 not for MOAI v1.5 - although the change is simple to apply to 1.5 )

 src/moaicore/MOAIBox2DWorld.cpp                  | 104 +++++++++++++++++++++++
 src/moaicore/MOAIBox2DWorld.h                    |   1 +

 2 files changed, 105 insertions(+)

diff --git a/src/lua-headers/run.sh b/src/lua-headers/run.sh
old mode 100755
new mode 100644
diff --git a/src/moaicore/MOAIBox2DWorld.cpp b/src/moaicore/MOAIBox2DWorld.cpp
index 943cbf0..20b39fe 100644
--- a/src/moaicore/MOAIBox2DWorld.cpp
+++ b/src/moaicore/MOAIBox2DWorld.cpp
@@ -46,6 +46,8 @@ MOAIBox2DPrim::MOAIBox2DPrim () :
  mDestroyNext ( 0 ) {
 }


+
 //================================================================//
 // local
 //================================================================//
@@ -600,6 +602,107 @@ int MOAIBox2DWorld::_getAutoClearForces ( lua_State* L ) {
  return 1;
 }

+// local
+ //================================================================//

+// RayCast modification from: http://getmoai.com/forums/post2723.html?hilit=raycast#p2723
+// Additional box2d modification to return fixtureIndex as well.
+class RayCastCallback : public b2RayCastCallback
+{
+public:
+    RayCastCallback()
+    {
+        m_fixture = NULL;
+ m_point.SetZero();
+ m_normal.SetZero();
+    }
+
+    float32 ReportFixture(b2Fixture* fixture, const b2Vec2& point, const b2Vec2& normal, float32 fraction, uint16 maskBits)
+    {
+        
+ b2Filter filter = fixture->GetFilterData ();
+

+ //MOAILog ( state,MOAILogMessages::MOAIRayCast_MaskBits, maskBits );
+ if( (filter.categoryBits & maskBits) != filter.categoryBits )
+ {
+ return -1; 
+ }
+ /*if( ( MOAIBox2DFixture* )fixture->IsSensor()){
+ return -1; //filter
+ }*/
+
+ m_fixture = fixture;
+        m_point = point;
+        m_normal = normal;
+
+        return fraction;
+    }
+
+    b2Fixture* m_fixture;
+    b2Vec2 m_point;
+    b2Vec2 m_normal;
+};
+
+//----------------------------------------------------------------//
+/**     @name   getRayCast
+        @text   return RayCast 1st point hit
+
+        @in     MOAIBox2DWorld self
+        @in     number p1x
+        @in     number p1y
+        @in     number p2x
+        @in     number p2y
+        @out    bool true if hit, false otherwise
+        @out    number  hitpoint.x or nil
+        @out    number  hitpoint.y or nil
+ @out MOAIBox2DFixture fixture that was hit, or nil
+*/
+
+int MOAIBox2DWorld::_getRayCast ( lua_State* L ) {
+ MOAI_LUA_SETUP ( MOAIBox2DWorld, "U" )
+ float p1x=state.GetValue < float >( 2, 0 ) * self->mUnitsToMeters;
+ float p1y=state.GetValue < float >( 3, 0 ) * self->mUnitsToMeters;
+ float p2x=state.GetValue < float >( 4, 0 ) * self->mUnitsToMeters;
+ float p2y=state.GetValue < float >( 5, 0 ) * self->mUnitsToMeters;
+ uint16 maskBits = ( uint16 ) state.GetValue < u32 >( 6, 0 );
+
+ b2Vec2 p1(p1x,p1y);
+ b2Vec2 p2(p2x,p2y);
+
+ RayCastCallback callback;
+ self->mWorld->RayCast2(&callback, p1, p2, maskBits);
+
+ if (NULL != callback.m_fixture)
+ {
+ b2Vec2 hitpoint = callback.m_point;
+
+ lua_pushboolean( state, true );
+ lua_pushnumber ( state, hitpoint.x / self->mUnitsToMeters );
+ lua_pushnumber ( state, hitpoint.y / self->mUnitsToMeters );
+
+ // Raycast hit a fixture
+ MOAIBox2DFixture* moaiFixture = ( MOAIBox2DFixture* )callback.m_fixture->GetUserData ();
+ if ( moaiFixture )
+ {
+ moaiFixture->PushLuaUserdata ( state );
+
+ return 4;
+ }
+ else
+ {
+ return 3;
+ }
+ }
+ else
+ {
+ // Raycast did not hit a fixture
+ lua_pushboolean( state, false );
+
+ return 1;
+ }
+}
+
 //----------------------------------------------------------------//
 /** @name getGravity
  @text See Box2D documentation.
@@ -998,6 +1101,7 @@ void MOAIBox2DWorld::RegisterLuaFuncs ( MOAILuaState& state ) {
  { "setGravity", _setGravity },
  { "setIterations", _setIterations },
  { "setLinearSleepTolerance", _setLinearSleepTolerance },
+ { "getRayCast", _getRayCast },
  { "setTimeToSleep", _setTimeToSleep },
  { "setUnitsToMeters", _setUnitsToMeters },
  { NULL, NULL }
diff --git a/src/moaicore/MOAIBox2DWorld.h b/src/moaicore/MOAIBox2DWorld.h
index 61a6641..7d0880c 100644
--- a/src/moaicore/MOAIBox2DWorld.h
+++ b/src/moaicore/MOAIBox2DWorld.h
@@ -98,6 +98,7 @@ private:
  static int _getAutoClearForces ( lua_State* L );
  static int _getGravity ( lua_State* L );
  static int _getLinearSleepTolerance ( lua_State* L );
+ static int _getRayCast ( lua_State* L );
  static int _getTimeToSleep ( lua_State* L );
  static int _setAngularSleepTolerance ( lua_State* L );
  static int _setAutoClearForces ( lua_State* L );

So there you go. Raycasts with masking.
If I only want to shoot UFOs with my lasers, not the clouds in the sky, now I can.

So how do we use this in game?

Somewhere in your game code you'll have something which creates your MOAIBox2DWorld.
You'll be calling the getRayCast method on this object.

gameworld = MOAIBox2DWorld.new ()

Then somewhere you'll need a function to actually cast the ray and return the data back.
The function returns several parameters (typical for Lua).

  • Whether the ray hit something or not, 
  • the X co-ordinate of the hit,
  • the Y co-ordinate of the hit 
  • the object with a category matching the maskBits that the ray hit.


return gameworld:getRayCast( x1,y1,x2,y2, maskBits)



Sorry for the ugly formatting - I'm sure there's a nicer way to present a UDiff.

Have fun.


Special thanks to FiveVoltHigh.com for getting me started with their initial tutorial on patching MOAI with support for RayCasts.

http://www.fivevolthigh.com/2013/10/moai-exposing-box2d-world-ray-casting-to-moai/


Thursday 24 July 2014

Review the Ancients: Dynatron Mission - Mastertronic 1987

Written in 1987
Coded by Paul Hargreaves
Music: None
Published by Mastertronic
http://www.worldofspectrum.org/infoseekid.cgi?id=0001559

Play it online http://jbacteria.retrolandia.net/48s?dynatron.tap
Thanks to http://jbacteria.retrolandia.net/ for hosting it and many other games.

Twenty Eight years ago, Two 13 year old boys were sat in their living room after school.
A new game had been acquired. One of them places a tape into the deck of the Spectrum +2 and 3 minutes or so later, it loads.



The loading screen showing an armoured space marine in what appeared to be MotoX armour, the cassette box looking like a scene from a sci-fi movie.

Having both seen Alien and 2001, the atmosphere could be cut with a knife.

The game loaded and play began. The case lay strewn across the floor in the usual manner - we didn't need instructions - we were kids - we knew how to game!

The space marine glided effortlessly into the Novar base on a personal hang glider and landed at the starting screen, all was quiet apart from a heart beat - rendered through the beeper with a Chwee Choo sound.

We quickly got to grips with the controls. Jumping was tricky but the added power boost made jumping large distances possible and tricky terrain easy.

Chwee Choo

The first room seemed easy enough, no enemies - moving to the right presented some sort of ledge, moving quickly.. Woah, stop. Gas traps. It's just gas, it'll be OK in the space suit. Using the power run, We attempt to run through the gas but alas the space marine dies with a shrill and a contorted image. Looks like the gas eats through the suit. down to 2 lives.

Chwee Choo

Carefully timing the run until after the gas has dissipated, yields the next room. Aliens and a laser firing into the rock in a pit. A quick round of weapon fire should take care of the aliens and we'll leap over the pit..  OK, where's the weapon? Can't see the weapon right now.

Chwee Choo

The aliens seem to be moving in a predictable pattern, we'll be fine as long as we stay out of their way. Oh no! An alien coming from the previous screen, that screen was clear, it must have followed me. One life left.

Chwee Choo

Avoiding the aliens, we jump up to where the the laser pit is and power run and jump over the pit. Trap avoided!

Chwee Choo

The next room has a moving platform. We leap onto the platform and ride it over to the other side.

Chwee Choo

We're then presented with two hydraulic rams moving up and down aside a hole in the ground, our obvious destination, a quick leap down towards them - Boing, a trampoline propels us towards the rams. Not wanting to touch them - we hold back and wait until they are high enough to pass between them and drop down the hole.

Chwee Choo

The next room is strange, no hazards at all. Just some arrows on the ceiling pointing up and a moving floor, moving towards the right. We attempt to jump off the ledge towards the exit. What is this? We're floating up - but we can move mid-air. We move towards the end of the arrows and fall. Obviously these have a finite influence over localized gravity. We move left, towards the only exit. The moving platform prevents us from simply walking, instead we power-run.

Chwee Choo

The room to the left appears to be a large chunk of tech, but it blocks our progress, even power jumping cannot clear it. Above the tech is a hole in the ceiling, it must be the chasm the moving platform carried us over. To the left of the tech is an exit to another room.

Chwee Choo

Back to the right then, up the lifter and jump up to the previous screen, avoiding the hydraulic rams. Boing. The trampoline catapults us towards the sheer cliff - but not high enough. There has to be a way up. Maybe a run-up, between the rams, landing on the trampoline and power jumping will be enough to get us up to the top.

Chwee Choo

Boing, we're at the top of the cliff we came down earlier. This was the wrong way. Just get back onto the moving platform. A mis-timed jump meant that the marine slid down a surface and landed in the screen with lots of tech. We'd have to go back to the gravity lifter, avoid the rams and use the trampoline jump again. This is tricky stuff.

Chwee Choo

Eventually we make it and slide down the surface on the other side. Placing us at the other side of the tech obstacle. We walk to the left and see bladed balls falling slowly into what appears to be lava or acid, in any case it's hot and bubbling. Above us is a pit with lasers.. hmm, I wonder if jumping down the pit at the start would bring us here.

Chwee Choo

A running jump over the lava seems to be the only way. We'd have to wait for it to be clear otherwise it'll be death from bladed balls.

Chwee Choo

Death it was. A misstep, landed us in the lava.

Shrrreeeeeeelll 
No Men Left - Game over.

The instructions on the case inlay were studied. Unusual for us, but this game was hard! Where is the weapon? On the case there's a weapon. The cover-art shows a weapon very clearly.
There, right there in the instructions, it says you're armed.. Where's the gun?!

It appears that our marine forgot his weapon. There is no combat in this game.

I mentioned "We" a lot because it was my Brother and I taking it in turns to see who could get the furthest, and although the preceding paragraphs may have been long and detail heavy, it doesn't even come close to the amount of time and effort it actually took to make it this far. The failed attempts, the deaths. Death by aliens, death by hydraulic rams, death by gas, by lasers, by bladed balls. But it was interesting.

We both still have muscle memory dedicated to defeating the first few rooms of this game. Then it turned out that the majority of the rooms described so far could have been skipped by hopping down a hole guarded by a timed laser.

This game was intense.

The constant heart beat kept the tension and the shrill of death was actually something quite unpleasant and was feared.

Each room was filled with frustrating and often deadly obstacles to be overcome, but with practice and patience - it was possible. All the while the marine's heartbeat would pound in our ears - Chwee Choo.

Over exerting or scaring the marine would increase his heart rate and would mean he couldn't perform power runs or jumps; meaning that you had to wait for him to calm down before you could proceed. Run or power jump too much, dangle from moving platforms for too long or fall too far and your heart will be pounding with the marine's. Chwee Choo-Chwee Choo-Chwee Choo.

After many hours of play, we finally made it to the Bomb room in the Novar base. A siren blares and a timer on the screen begins to count down - we now have to make it back to the exit room we passed some screens ago and a short time it seems to get there.. now where was it? A mad scramble back up through screens we fell from, alternate paths with new challenges - never before experienced and must now be overcome while under time pressure. All the while the marine getting more and more out of breath.

This game was terrifying. It lured you in with it's simplicity and then beat you over the head.

It's graphics were colourful, yet alien. The locations often seemed functional in some odd way. The traps were clearly identifiable (a sign of good level design). A great deal of care had been taken in this game's construction - and it was all made by a single person.

In the first few screens, the player learned pretty much everything they needed to play the game. They also got a taste for the danger which lay deeper into the complex.

The lack of a weapon was novel. It meant that players had to think their way out of situations rather than rely on combat prowess. This was a thinking boy's game - A game which rewarded patience and clear thinking. There was an element of luck, but mostly death came because the player messed up.

Careful leaps, timed jumps and a clear head were needed to progress to the ultimate goal.

I'll be honest, My Brother and I never made it back to the exit screen on any of the levels (or at least he never told me that he did, I imagine he would have as it's kind-of a big deal). We got close, only a couple of screens away. But the bomb would always detonate and it was Game Over.


A lot of people cite games like Manic Miner, KnightLore and AticAttack as their classics for the ZX Spectrum.

However for me, near to the top of my list is Dynatron Mission. A game so tense, so difficult and so atmospheric I will never forget it. It is unfortunate that it remains an obscure title that only a handful have played. I encourage you all to play the game - there is a link at the top of this review.

I do wonder whether a game like Dynatron Mission would be possible on modern platforms. The difficulty curve might put most people off. I do wonder why it enraptured my Brother and I. We had other games, but nothing had the atmosphere, especially when played along-side Holst's The Planets Suite - played on a record player.


I've been unable to find recent activity for Paul Hargreaves on-line. I would like to thank him for this game. It has certainly been an inspiration. 

Monday 14 July 2014

Review the Ancients: Death Stalker - Codemasters 1989

Death Stalker

Written in 1988
Coded by Tony Warriner
Music by David Whittaker
Produced by Tag Computer Games
Published by CodeMasters in 1989
http://www.worldofspectrum.org/infoseekid.cgi?id=0009330

Imagine: You're a 15 year old with a Spectrum. It's summer in 1989. It's raining outside and there's nothing on the 4 channels the UK had to offer. You've just purchased a new game for the computer, it's a budget title priced at £1.99, but you don't care. Some of the best games were budget games anyway.
The box art promised an adventure similar to childhood movies like Beast master or Conan the Barbarian - which I was probably too young to watch, but watched them anyway.

The tape was placed into the tape player and 3 minutes later the game had loaded to an amazingly atmospheric David Whittaker tune. So far, so good. I'm gonna slay me some orc men!

The player was placed in a forest without any guidance, clues or any story as to how he became to be there in the first place. The forest drawn in a monochrome red with green leaves, mostly bare branches selling the feeling of death and dread - this was not a safe place to be.

The player is attacked early on by skeletons and orcs which are fairly quickly dispatched with your sword or power. You are faced with a choice. Should you move to the left, you are faced with a tower with a bird-like creature waiting in a window. If you move in more, he swoops down and attacks you forcing you to either retreat or to fall into a pit of spikes. There is no way out of this pit, should you survive the fall you cannot climb out again, your only option is suicide by jumping onto the spikes.

Move to the right and you see a hole in the ground and more monsters. They are quickly killed. Holes in the ground are never good so deftly leaping over the hole and moving to the right seems the most sensible course of action. To the right is another building with another bird creature blocking your path.

Down the hole it is then.

You fall down the hole and land in a dungeon room with ghosts floating around. They cannot be attacked. If they touch you, they'll hurt you, damage being shown by the state of four skulls on the bottom right of the screen - alas it seems these do not represent lives; however as you fall you notice something remarkable about how this game is displayed.

Unlike other flip screen games of the era, Death Stalker doesn't show you anything you can't see from your current vantage point. So in order to see what's around the corner, you have to venture forth. This works really well where there are doors, pits and ladders. You can see the ladders, but you can't see what's on the platform above you. You'll have to climb them and see for yourself.

The idea behind this was brilliant and added greatly to the atmosphere. It is also to my knowledge, the only spectrum game that did this.

The presentation of the game visually was pretty good overall, it's graphical style lending itself nicely to the fantasy adventure style. The combat animations left a lot to be desired and the overall feel for the controls was sluggish. This could mostly be forgiven. Jumping would prove to be quite a pain. Jumps would often need to be timed very accurately to progress - or perish in a pit of spikes.

The game ran at a poor framerate for the most part, it would periodically slow down while a piece of scenery came into view or disappeared. I can understand this, it was doing a lot with the limited power of the spectrum. The speed problem was forgiven and there were certainly worse examples of performance.

Killing creatures caused items to drop. Keys, food, potions and other goodies which would help in your quest. There was a primitive verb based inventory system. It was slow to use, but functional.

There were also NPCs to talk to - prisoners to rescue. A nice touch making the dungeons feel alive and giving the player purpose. Even the ghosts would talk.

Death Stalker's biggest problem though was that it had more than a fair amount of instant death traps and areas with no way to return, whose only end was a gruesome death.

Spike pits aplenty and pits of acid. The game became a tedious memory game instead of the hacking slashing adventure it wanted so hard to be, which was a shame really.

If you were lucky enough to make the correct choice, you'd better remember what you did and don't be curious about the other door or wonder what's just off the ledge, it'll be certain doom if you do.. or maybe not, there was no way to be sure.

The dungeon appeared to take joy in killing or trapping the player without mercy. Only by knowing the correct path did you stand a chance. Then again, the game was called Death Stalker - what did I expect?

Once your health had depleted, it was game over. You'd have to start all over again from the beginning.

Back in the speccy days, this wasn't such a shock - but can you imagine what would happen if a game pulled that trick today? Current difficult games like Dark Souls had nothing on this.

Death Stalker is a game which I wish was a bit better. It could have been a classic. Instead we have some good ideas and a nice soundtrack and a dungeon that wants to kill you, horribly.

I really wish CodeMasters hadn't put the legal blocks on their games being reproduced or stored on-line. It means that games like this will disappear into obscurity. I believe that there's still something to learn from DeathStalker; After-all, I still remember it fondly.

Remembered for being a little awkward and a cruelly difficult - but remembered all the same even after all these years.


Tony Warriner now works as the co-founder of Revolution Software and he's made some games you have probably heard of: Lure of the Temptress, Beneath a Steel Sky and Broken Sword.
Still Adventuring.




Saturday 12 July 2014

Retro Music - Why is it cool? Because Batman!


I remember fondly growing up with a Sinclair Spectrum +2, it's limitations were largely unnoticed by me.
Instead, it was a source of constant wonder and of all the things in Speccy gaming that I was the most impressed with was the music. Mostly the 128k music, but occasionally 48k music too.

In fact, any game which didn't have decent music was seen as inferior to even sub-standard games with good music.

One such game was a CodeMasters game called Death Stalker.
I'll probably do a review of Death Stalker at some point as although it wasn't brilliant, I believe that there were some truly visionary things in that game.
It's a pity that the actual gameplay was so unfulfilling in the end.
However the thing which I did truly love with Death Stalker was the music.



The music was written by David Whittaker, a musical hero of mine.

I love the way he overcame the 3 channel limitations of the AY chip to produce something very atmospheric and impressive. It kept me playing this game when all other senses told me to stop.

It is a shame actually that CodeMasters refused to make their back catalog available to emulators. The internet is littered with details of a great many spectrum games. However a lot of the older CodeMasters games are missing from this archive simply because people cannot find them to play on-line; instead relying on pirated versions or original tapes. These tapes are

Another David Whittaker masterpiece which stuck with me was the music for Trantor the Last Stormtrooper

This music sounds a little rough and Lo-Fi - however when you consider that this is played on a beeper without the aid of a sound chip. This is the Z80 processor going "hell for leather", "all-out" to render drums, bass, melody and pads. This is a technical masterpiece and I would love to remake this.

I recently remade the titles music for Robocop. The music was originally written by Jonathan Dunn - another hero of mine - and this music stuck with me for many years.
It was even used in an Ariston TV advert.



Remaking Retro music is actually quite difficult with modern tools as it's very tempting to over-do the composition.

It's important to remember that the original composers were working within a very rigid set of constraints. To do the tune justice, you should use a limited set of instruments and effects.

The C64 version of Robocop sounds similar but has some additional portamento effects, which work quite nicely. I personally prefer the ZX Spectrum version, but each to their own.

A great site to visit if you're interested in remixes of older C64 tunes is http://remix.kwed.org/

So why is it cool?

Well, my opinion is that when faced with restrictions, we can often find amazing things within ourselves. We are at our most creative when the resources are scarce.

That's the deepest pit of human creative desire right there, and that my friends - is amazing!


In closing, I'll leave you with Storm Bringer.

Take it away David (yup Mr Whittaker again)


You're welcome... ;-)