Thursday, July 30, 2020

Summer release

Dear invisible friend

This is a weird summer, the good thing is that the confinement made our island look quite different, that is, cleaner landscapes, animals here and there and crystal clean waters. The bad thing is that economy sinks and stinks..., but at least I keep coding whenever I have time.

Please find binaries at  

  • Princess position fixed
  • Many TDictionary changed to THashMap
  • New TTriggerDispatcher FreezeCamera() and UnlockCamera()
  • New level Scifi Movie!
  • Now cables are also affected by gravity
  • New element VerticalLight
  • Now Darkness works with Camera (panning and zoom)
  • New enemy FlyingEye 
  • Now Turret laser takes into account any possible actor and stops in in its path
  • All laser enemies now inherit from common class TEnemyWithLaser
  • Some minor optimizations in TColorTileHandler
  • TLavaEruption behaves better
  • Now if an enemy is sleeping and gets damaged it will wake up
  • Fixed some Z issues with Cables and Ropes when zooming with camera 
  • Now when arrows fall some particles are shown and ther arrows dissapear with alpha 
  • Now selecting level  has some flocking effects

  • Sprite quads massively improved 
  • THashEx.Generic() improved
  • New TMem.Move192BytesAligned(), Move192BytesUnAligned(), TMem.Move16Bytes(), TMem.Move20Bytes(), TMem.Move32Bytes(), 
  • THashMap<K, V> improved
  • 2D camera improved
  • New property TSprite.EmitterMask
  • New TFlocking class
  • New TVectorEx.Limit(), Magnitude() and Square(), TVectorEx.FastLength(), FastDistance()
  • New TMath.CenterOfTriangle(), TriangleHeight()
  • New TFloatHelper.IsGreaterThan(), IsLessThan()
  • New TRectF.Sort() and Round()
  • TPerspectiveCamera properties FOV, Distance and Limits seems accurate now
  • New TCamera2D.Move()
  • TMenuItem.Default now sets Option properly
  • New TScreen.SetScissor(), GetScissor() and RemoveScissor()
  • Sprites, Laser and Fluid drawing improved
  • New TCamera2D.FitToAreaWidth()
  • Little optimizations in loops here and there, making all vars local
  • New TRGB.HasAlpha()
  • Now TMessage.Data is a plain TObject rather than an interface
  • New types T8,T16,T32,T64
  • Now Cables and Ropes cast shadow 
  • Now Cables and Ropes occlusion against camera Z works better
  • Spring behavior is now more precise
  • Z occlusion test for particles improved
  • New TD3DDriver.SetViewport()
  • New TGraphicDriver.GetFullView()
  • New TFloatHelper.IsGreaterEqualThan() and IsLessEqualThan()
  • when drawing a layer, Glow applies only if not completely surrounded by tiles
  • New TRGB.CopyFrom()
  • New TVectorEx.CopyFrom()

Saturday, May 2, 2020

Confinement release, weird year this 2020

I hope you are all safe and well. Due to bloddy coronavirus thingy I had plenty of time to write code so here we go!

Found binaries at OneDrive, main changes:
  • New level Fear!
  • New boss Brachion
  • New weapon Amus
  • New element Cable

Here is the full list changes:

  • New element TCable
  • Weird corrects its angle when taking a new path
  • IInteractive.Interact() implementation was crap, improved
  • New element OldLamp
  • THero.CanJump() improved
  • New THero.TileOnBottom()
  • Now Ropes use a better visibility test 
  • New TTriggerDispatcher GetResult(), ScriptCount() and SumVar(), Print(), ClearTileAt(), ClassCount(), CopyVar(), RemoveEntities(), SpawnClass(), AlphaLayer(), SetShake()
  • TGameSprite.SetGameServices() is no longer virtual
  • New enemy Brachion 
  • Now platform's angle is taking into account (not working 100%)
  • New Kurkani bitmap
  • Nnew Gatashi bitmap
  • TGameSprite.SetGameServices() is no longer virtual
  • New enemy Brachion 
  • Now platform's angle is taking into account (not working 100%)
  • TGamesprite renamed to TActor 
  • Actor.Master is now Actor.Host
  • New property TActor.AutoPriority
  • Game was not cleaning the sound cache between levels
  • New element PhoneBox 
  • Now Turrets show a think red laser when chasing players
  • New property TCotton.MinDistance
  • New property TLight.Animation
  • New property TParticlesWrapper.MinDistance
  • New property TBasicTurret.LaserColor 
  • New property TBrachion.LaserColor 
  • New property TSkeleton.MinDistance
  • New property TNPC.MinDistance
  • New property TPrincess.MinDistance
  • New IBaseItem.IsCollectible()
  • New THero.GetCollectible()
  • Now shop items are sorted by name
  • Now after entities are created, the cell attribute is cleared
  • Now shadow Z is calculated dynamically
  • TActor.CorrectGravityOrientation() improved
  • Now achievements are stored in a file and no longer internally
  • New TCable.Perturb()
  • Runes are no longer keep in the profile, TRunesHelper now keeps all runes information for the current game
  • New TTriggerDispatcher.Sleep() fixed
  • New class TEntityTracker that helps any entity to find the shortest path to a target
  • ExplosiveBarrel behaviour improved
  • New Actor property Range 
  • Actor.DestroyArea() improved
  • Hero can now go down from TwoWays (like clouds) platforms pressing down + jump
  • New attribute GRAVITY_UP so a map can have a different gravity deom design
  • New method TActor.GetPlatformFromCenter()
  • New TActor.ContinuousSpriteCollision() that helps fast moving sprites collisions
  • Now arrows adjust correctly their angles when gravity is up
  • New TActor.AdjustPositionToTile()
  • Now darkness can rotate lightmaps coming from entities
  • TMachineGun many fixes
  • Changed some Sin() and Cos() by SinCos()
  • New element IceSpike
  • New pickup TCollectible
  • Now some enemies uses new shadow queues 
  • New properties TEnemy.PainChance and PainDelay
  • All TStrings changed to TList<string> or TStrings<T>
  • New TTriEye properties ContinueAfter, FireAfter, ShootingProbability
  • TActor.ContinuousSpriteCollision() improved
  • New element SuperBlob 
  • New property TActor.InitialEnergy
  • New explosion with particles, I believe they are cooler
  • When bomber is going to be alerted now also checks that there is nothing solid in between
  • Now Arrows inherite from TBullet and fixed a bug where an arrow did not know that parent (ArrowSpawner) was Dead
  • New weapon Amus
  • Fixed a bug where an actor could die many times in the same frame 
  • New TSoundDispatcher.DelayedSound()
  • Now dynamic priority takes into account liquids 
  • Now when jumping the speed from platforms is take into account giving more inertia
  • Now sound system tries also to use the youngest sound when channel is full 
  • New achievements...
  • New enemy Rotating Spike 
  • New TActor.GetEdgeFromVelocity()
  • New property TActor.ExplosionTime
  • Seems BASS64.dll is modifying MMX overflow flag while playing, so a workaround was created
  • New effect to shake tiles
  • New ITriggerDispatcher.
  • Bat fixed
  • Scepter won't stop on solid items
  • Added lightness to levels
  • Now some shields can reflect a laser
  • New bridge elements 
  • Hidden doors are no longer shown in minimap
  • Up spikes are now correctly aligned
  • Poison was not recovering after 10 seconds 
  • Now fish when is out of water feels the gravity 
  • New Players.GetHeroes(TRect) that improves the performance
  • New shop/inventory item LastExecution that helps with cadency
  • New extra THomingMissile
  • Hero extras handling improved
  • Now hero uses a buffer jumping before falling
  • New generic modifying cube system
  • Now maps can have configured slopes
  • New ISprite.GetLayer(), DistanceXBetween(), DistanceYBetween()
  • TMem.Scan32() in the 64 bits version was flawed thus last 64 bits version of binary was broken
  • New TSurface.Tween()
  • Now triggers can have parameters
  • New TParticleEmitter properties AlphaFrom/AlphaTo 
  • Many functions in TSprite are no longer virtual 
  • TSprite.OnChange does not update collisions if collisions has not been created yet
  • New TSurface.Replace()
  • THashEx.Generic() optimized when size is multiple of 4 (four bytes at a time)
  • New TScreen.DrawSurface(surface, rect, z)
  • New TMap.ScriptCount(group)
  • New TScript property LinkedGroup
  • New TMemVar.Sum()
  • Many loop vars change from integer to NativeInt when used with pointers as offset so code generated is better
  • New TMem.AreEqual<T: record>(A, B: pointer; aSize: cardinal): boolean
  • New TSoundFactory.ToMono()
  • Now TSurface.FlipX is much faster
  • TD3DSurface.FillSurface() performance when no colorkey improved
  • TKinematic improved
  • New TSwap<T>.SwapContent(A, B: pointer)
  • New TMath.CenterOfPolygon()
  • New TMath.ThrowAngle()
  • New class TCameraPrimitives, for primitives with camera 
  • New TParticleEmitter.IsStarted()
  • A few optimizations in loops with field variables from object in many classes
  • TLayer.GetCellNoCheck() used in some functions rather than GetCell()
  • New TInterfaceHelper.Copy()
  • Now individual layer tiles can be glowed
  • New TLayer.GetDistance(), GetTileRect()
  • New property TLightSprite.Blur
  • New TRGB.Dolly(), Martinique()
  • New TParticlesTextureCache class
  • New ISprite.SetEngine()
  • New TColony<T>.Exchange()
  • New TCollision.CircleInRect(), TCollision.CircleInCircle(), TCollision.LineInRect(), TCollision.PointInTriangle(), TCollision.RectInCircle(), TCollision.TriangleInRect()
  • Now once per second system checks for "aged" buffers in pool in order to discard them (10 seconds at the moment)
  • TSpriteEngine.GetSurface() performance improved a little bit
  • Now a TKinematicArm can have many TKinematicSegment
  • New TClamp<T> helper functions
  • New TObjectHelper.CopyObject<T>
  • New TMath.Clamp(), DistanceManhatan(), NormalizeAngle180(), Atan2(), Log10(), Log2(), Sgn(), Ln2()
  • TPathResolver finally works 100%
  • New class TTickHelper
  • New TDirectionHelper.Rotate180(), Rotate90(), Rotate270()
  • New TMath.InverseNormalize()
  • Particles now handle much better when alpha changes with textures (dictionary of pool)
  • New TMath.NextPowerOfTwo()
  • New BB.Helper it contains all BB classes and records helpers
  • New TDummySprite.GetLayerPosition()
  • New TSurface.Copy(), MirrorX(), MirrorY()
  • Now Cadency in .ini, .extra are set as milliseconds
  • New TSprite.GetDelta()
  • Now the precise collision system supports FlipX and FlipX (besides zoom and angle)
  • New IObject.GetClass()
  • New TFloatHelper.Is1()
  • TCollision.TestBB() improved
  • TSurface.Rotate() improved
  • Now in looped maps the offset can be set (does not have to be zero)
  • New TParticleEmitter.Random
  • New TParticleEmitter.RandomRate 
  • New TSprite.GetCenterF()
  • New class TCPU
  • New TRGB.Gradient()
  • Now TSprite FlipX()/FlipY() also flips BoundingBox
  • TSprite.GetBBF() improved
  • Particles cache system does not longer need a group
  • New property TParticleEmitter.RandomAngle
  • New TMath.Normalize()
  • Many exceptions changed to asserts
  • sprites.CenterX/Y were not taking into account CoordinateOrigin...
  • Better management of particles 
  • New unit BB.E3D.Types
  • New Particle Emitter pool
  • New motion tiles has color property in .ini file
  • New TRGB.HasColors()
  • Updated to last version of bass.dll
  • New FloatHelper.InBetween()
  • Added moving slopes tiles in Maps
  • Fixed slope sizes when no colorkey
  • TStrings<T>.SetItem() was not working properly
  • New TGraphicDriver.OnClear event
  • TSpatialPartitioning.GetArea<T> improved when area occupies only one cell
  • TSprite properteis Painted and Locked removed
  • TSpriteEngine.Find<T>() casting improved
  • TSpatialPartitioning.IterateSprites<T> casting improved
  • Scripts rollback handling improved

Monday, October 21, 2019

Martina is coming! (and also a new version of HBF)

Oh well, is never too late to have another baby, so happy...

In the meantime I always find time to change little things here and there. Most important changes since last time:

  • New trigger link types rollback and many
  • New render when openning secret doors
  • New extras: Magic wand, blue ball
  • New enemies: mine bomb, wall bouncer, tri eye
  • New explosion types
  • New elements: alarm, candy machine, frame
  • New weapons: machine gun
  • New level Lifting
  • New tool Path Editor
  • New effects in surface like: displacement, connecting dots, 
  • More control over UV in sprite textures

Found binaries at OneDrive

New level:

New effects:



  • New trigger action ClipEntity()
  • Now Machine gun can also shoot up
  • Now Basement can throw homing missiles
  • Teleport was not always handling correctly the collision with guests
  • Now when a hero is killed its seeking homing missile looks for other heroes if available
  • Robot can also now throw missiles 
  • New TPlayerHandler.OtherHero(hero)
  • Now missiles do some smoking trail 
  • Now TSpriteDispatcher has new properties: Tile, SpriteProperty and SpriteValue
  • New trigger ResetTriggerSelection()
  • Fixed some issues when entities were crushing
  • Fixed an issue when a fast platform was going up and hero was jumping
  • Fixed an issue with tapes not checkking both sides when facing was equal to none
  • Now Bouncing Laser is aware of hero's immunity
  • Bouncing laser now also bounces with solid items
  • Weird now also check for solid items
  • New method TKeysHelper.Peek()
  • New method TEnemy.CanBeExcited()
  • Fixed a bug with none gravity items that they were checking collisions against the world
  • Now only when shopping hero can sell items
  • Now Bat is able to hang upside in moving platforms
  • Now Missiles also destroy enemies 
  • Now Inertia is accumulated 
  • Now explosions also affects moving platforms 
  • New element Tube, it throws air up, pushing items, hero and enemies
  • Collisions with moving blocks improved
  • Collisions with platforms are more stable
  • When pushing items they also stop with solid items
  • Platforms now can follow a Path
  • Fixed a camera bug when teleports where on same X
  • Mine can follow a  path
  • Now hero checks if solid items are piled at restarting position when dying
  • New level Lifting
  • Path helper now can handle more than one attribute 
  • New TSoundDispatcher.Count() to count all concurrent playing sounds 
  • Now when GameServices is assigned all published properties are already set 
  • Sounds position are update on even frames 
  • Now when landing on moving platforms ssLanding is set
  • New set of minimaps
  • Sprites priority changed to plus rather than minus
  • Improved a bit some internal callbacks
  • Laser improved
  • Shoes counter mechanism improved
  • Now when an arrow hits a solid tile it will fall rather than dissapear
  • property SolidFromBottom renamed to OneWay
  • Now when a mine moves if bounces if a solid tile in on its way
  • Now camera when zooming out distinguish between horizontal and vertical distances
  • More Abs() replaced with TFloatHelper.Abs()
  • New TGameSprite.SolidItemAlignedOnTop()
  • TGameSpriteIsSolid() no longer returns a boolean 
  • New GameSprite interfaces Window and CameraHelper
  • TestWorldWollision() reordered to a more real approach
  • Now Tube force is done with Power property
  • More use of TFloatHelper.IsZero(), TFloatHelper.NotZero(), TFloatHelper.IsGreaterThanZero(), TFloatHelper.IsLessThanZero(), TFloatHelper.IsGreaterEqualThanZero()
  • Now in order to push a block you need some power
  • New Path styles horizontal and vertical
  • New item glove, so heavy blocks can be pushed
  • Fixed a potential AV error when a guest was in the teleport (2 seconds) and then set back to state ssMoving but it was already dead, now Teleport is no longer in charge of the timings but the guest
  • Now Trigger system can zoom in/out the camera 
  • Fixed an issue when updating the level on an extra the previous item was not released after purchasing it
  • Now Tube can be up side down
  • Fixed an issue with TBouncingLaser at certain angles 
  • Fixed some more Z issues
  • TBasement now inherits from TSpawner
  • Now THoming can follow a path from the new path editor
  • New TGamesprite.Velocity (replaces impulse and inertia)
  • Now when jumping oneway platforms hero won't stop 
  • Now using {$I} to includew common definitions
  • Now different scanlines can be loaded
  • Some inverse multiplications here and there
  • Platforms now also appear in minimap
  • New property TArrow.FallWhenHit
  • Now arrows can burn
  • Now when hero attacks with a weapon that can different power depending on how long you press a button then it shows a bar
  • New trigger SetCameraRotation()
  • TBendArrow can also Burn
  • Now players are mapped correctly (J1,K,J2,J3 = P1,P2,P3,P4)
  • New types for ColorTiles: custom, expanding, etc
  • Changes when bouncing platforms to avoid -0 in Horizontal or Vertical speed 
  • Now during the same game if fight is win on a certain level then runes won't appear again in that level
  • Head fire collision with items improved
  • IsSolid() improved
  • Now TGameSprite.Execute() method has a param (useful to send params from scripts)
  • Now "Severe Gravity" uses paths created with the editor for some parabola missiles
  • Now "The Labyrinth" uses the new trigger type Rollback
  • Now secret doors show something different when opened
  • Stalactites are break differently when broken
  • New TMagicWand extra
  • Item.IsRepeatable removed
  • Item.IsActive removed
  • property InventoryItem.IsActive renamed to IsSelected
  • Hero.CreateItemsFromInventory improved
  • New TGameSprite.GetEmitterPosition
  • Basement, new property TimeToWaitWhenMultiple
  • Missile, new property callback OnTargetGone
  • Now a Mine does some rotating and zooming
  • New TEnemy.SleepAndWakeUp()
  • Now coins are stored in inventory
  • Now already thrown bombs can be picked up
  • New extra Missile 
  • DestroyArea() is more accurate
  • Now shop shows the quantity left
  • New  TGameSprite.CircleExplosion()
  • New property TBasicPlatform.CanDie 
  • if platform is moving in a tape and an entity is on top, then take that speed
  • New element Alarm 
  • Now the chat shows who is sending the message
  • Now TTriggerDispatcher can notify any observer about public triggers 
  • Now Cone is used, why it was not used?
  • Door, teleport is got a new texture map for darkness
  • Camera can now be Freezed
  • TPlatformBall got a new surface
  • New extra BlueBall, use them and then attack!
  • New IGameServices.GetParticles: IParticles
  • Now rather than TryXXX() functions interactible entities implement IInteractive (post, door, wheel, teleport, terminal, NPC)
  • New element and achievement Candy Machine
  • property AutoCenter renamted to AttachTo 
  • New WallBouncer enemy
  • IGameSprite renamed to IActor 
  • New TGameSprite.Face()
  • New TGameSprite.Yell()
  • New Shop item properties Cooldown (before was delay) and IsRechargable
  • New TGameSprite.DelayedExplosion()
  • New Enemy properties Deaf and Visibility
  • New weapon TMachineGun
  • -New THeroBullet class
  • TEnemyKiller now is used as base class for enemy bullets
  • New property ShopItem.Input (normal,accumulated,continuously)
  • Now max_items = 999
  • property AttachTo renamed to AlignTo
  • Now when entering teleports new particles are used
  • Now bombs have some randomness
  • New enemy Mine Bomb
  • New enemy TriEye
  • Kurkani now is shown in darkness
  • New TGameSprite DieOnLand and DieOnWall properties
  • New element Frame 
  • Now Laser take into account solid items 
  • New global var TGame.GD

  • Fixed a nasty bug that was slowning down the game when gravity for reversed, fast collision was not used because sprites were aligned at 180º
  • TSurface.AverageColor() is now a bit faster
  • New TParticleEmitter.Priority property
  • More info for screen pools
  • New IGraphicDrawer.Frame()
  • New TStrings<T>.AsText()
  • New TRect helper Clear()
  • New sprite property ZShadow 
  • Optimizing interface as TSurface with interface.AsObject
  • New ISelf.GetInterfaceEx() so [unsafe] references can be used, therefore Supports() is no longer used
  • Many minor performance improvements here and there
  • Direct3D Prepare() is now optimized for specific rendering methods
  • New Radix sorting
  • Fixed a silly bug in TBezier class that didn't generate the first step correctly (discovered after creating a path editor)
  • New TFloatHelper.Is270(), TFloatHelper.Is90() ,TFloatHelper.IsOne(), TFloatHelper.IsMinusOne() and TFloatHelper.Not1()
  • Aspect camera is not continuously recalculated but only when needed
  • Camera viewport() and CalculateProjectedTileCount() with some zooms were not correct 
  • New TFloatHelper.Max() and TFloatHelper.Min()
  • New path editor
  • New TAnimationSprite.RandomInitialFrame
  • Now using {$I} for common properties
  • No longer use of TGraphicDriver.Instance in the code
  • New TLayer.CleanTilesWithAttribute()
  • New helper TRect.Put() and TRect.New()
  • New helper TPoint.Put() and TPoint.New()
  • New RGB.Put() and TRGB.New()
  • New TVectorEx.Put() and TVectorEx.New()
  • Inlined methods used within the same class must be implemented first
  • Important functions where IShape was used now use TSimplePolygon, performance boost
  • Now TSpatialPartitioning.GetArea() exists quickly if there are no sprites in the whole grid 
  • Now TInputEx.GetCurrentCounter()
  • TFloatHelepr.Abs() is slower than standard one
  • class TSimplePolygon28 renamed to TPolygonTexcureColor, size is now 32
  • Bass DLL updated to latest version
  • New LinkType for scripts ltRollback, for those scripts that work as long as target is colliding, otherwise a rollback script is executed
  • Fixed an issue when locking more than once the same surface within the same tick
  • New TSurface.ConnectDots()
  • Rollback triggers now can have a timeout
  • Particles decimal rate 1.5 or 0.5 now work properly
  • New TSurface.GetAddressNoCheck()
  • New Sprite.EmitterType etDiffuse 
  • New sprite.CalculateNormal()
  • New sprite.CalculateSpecular()
  • sprite.GetRectangle() and sprite.GetRectangleF() now takes into account CoordinatesOrigin
  • New TScript.LinkType ltMany, in order to connect many scripts, if all are activated then execute the related script 
  • New class TEasing
  • New IParticleEmitter and IParticles
  • TSurface.ExtractPoints() improved
  • Now TParticleEmitter.SetImage() has a color parameter
  • TSurface.ExtractPoints performance improved
  • TRGB.Clamp() fixed
  • Surface blit() can now use ColorKey
  • TSurface.Rotate() was not working properly
  • New TSound.GetDuration 
  • TGraphicDriver.DrawSurface(), FlipX and FlipY removed 
  • New TSprite.ScrollTexture()
  • New TSprite.TilingScale(), to scale the UV of the sprite 
  • New TSprite.SecondarySurface, so to special effects with another texture
  • New property TSprite.TextureAddress
  • New TSurface.GetType()
  • New TSurface.Displacement(), to apply texture displacements 
  • New TSurface.ScrollX() and ScrollY()
  • Now surfaces are check for colorkey (maybe they are set but in fact no colorkey exists)
  • TSpriteEngine.Capture() now move bytes with TMem.Move32()
  • Many TSurface operations improved, using GetAddressNoCheck(), not always calculating crc, proper casting of integer vs cardinal, PCardinalArray, for rather than while, 
  • TSurface.ScrollY() now uses TMove.Move128()
  • New TMem.Scan8/16/32/64()
  • New TSprite filter sfGaussian
  • New TGraphicDriver.ClipRectAndTexture()
  • New TSurface.ReduceColors()
  • Finally sprite quads can be clipped
  • New TRGB.RGB2HSL()
  • New TSurface.Resize()
  • New TSurface.ColorCount()
  • New class TFixedPoint, to facilitate the fixed point maths
  • New TSurface.SetPixelNoCheck()
  • Now Sprite BB is only calculated when refreshing sprites 
  • Now surface rectangle is only calculated when refreshing surface 

Saturday, March 9, 2019

Happy birthday daddy!

I'm still improving the engines just because is lots of fun.

Found binaries at OneDrive


  • Many enemies can now follow a path 
  • New enemy BouncingLaser
  • Now boomerang does some curve
  • Turrets won't shot if there is a wall in between
  • Fixed TWeird when moving fast 
  • When an enemy is inside a bubble it won't kill hero
  • New SonicBomb item
  • Now any tile can be disintegrated
  • New achievement break a glass 
  • Collision top now also check for slopes
  • Ray was painting surface even if not visible
  • TPathHelper now also works in pixels
  • New property GameSprite.ItemsLayer since it is heavily used
  • Now TWeb disappear with alpha 
  • Some map changes
  • TGhost animation was not always correct
  • New TSegment enemy
  • Fixed a bug selling items
  • New TGameSprite.Coins property
  • New achievement "find all fruits"
  • New fruit items
  • New enemy TBasement that can launch missiles
  • Now TGmeSprite.Explotion() is more versatile
  • New TDoubleTurret
  • New test map so that new entities cab easily be tested
  • In debug mode one can create new entities on the fly 
  • New TBezierEnemy
  • Some services are preloaded as properties in TGameSprite
  • TGameSprite.GetCollisionData() does include himself as item
  • New THoming missiles 
  • New TRobot enemy
  • Edit window now shows a blinking cursor


  • Non cached surfaces are created in default pool
  • Surface hash is calculated when creating the texture so no lock is needed
  • Now when locking surfaces the read/write flags are used correspondingly
  • If collisions have no angle and no zoom, the fastest check is done
  • New TSimplePolygon, tailor made for direct3d buffers, now all sprites, primitives and particles are done using them
  • Now screen buffer management is more stable
  • Trying to avoid AddRef and Release methods for interfaces when possible
  • New TObjectEx.AsPointer()
  • Now TColony<T> deals with interfaces without AddRed/Release
  • New TColony<T>.Insert()
  • Maps iterates i, j rather that j, i (cache benefit)
  • New graphics buffer pool
  • TSprite.Timeout property removed, use AddTrigger() and Die() instead
  • Now maps pixel conversions are done with SHR/SHL rather than multiplying
  • Now spatial partitioning conversions are done with SHR/SHL rather than multiplying
  • Minor performance improvements in sprites 
  • SpriteLights are now also cached
  • New TRGB.NotEmpty()
  • New TVectorEx.NotEmpty()
  • Starting to use inline variables (Rio 10.3) as a performance optimizer (declaring managed variables after early exit or on certain conditions)
  • TOrthogonalCamera is back
  • Fixed some issues in the collision system
  • Fixed an issue when packing vars for hashing
  • New TAchievements.Behaviour property
  • Angle was not reversed when camera is available in collisions 
  • Now Screen.Fade() has a Z param

Tuesday, January 1, 2019

Happy new year!

This release was focused on improving the global performance, so now the game is about 20% faster. Aside from that now the game has shadows maps, light maps, a new enemy Turret and a generic Laser.

Found binaries at OneDrive, here is the what's new:


  • New element explosive barrel
  • Rope now ends with a circle
  • Observer Update() takes into account type of message 
  • Now heroes are spawned first so that they are aware about all other sprite coordinates
  • Cardride was broken since some releases...
  • Cable sparks now excite any mechanic enemy
  • Now sprites can be wake up
  • New GameServices.WakeUp(area)
  • New Crane entity 
  • Replaced MOD with AND when possible
  • Bomb, Titan and Worm can now sleep 
  • New trigger WakeUpEntity()
  • New IEmitter interface 
  • Solid layer is calculated when assigned the GameServices as .Layer, so GameServices.GetLayer(SOLID_LAYER) is no longer needed
  • New Compass shop item
  • New class TGameService for classes that need GameServices interface
  • New property TGameSprite.DefaultHorizontalSpeed
  • Now menu key can be set in hbf.ini
  • Net keys data moved to TSession
  • All input (local, remote and impersonate) goes to new class TKeysHelper
  • Some Z definition changes
  • Files clean up
  • New enemy RollingBox 
  • New inventory item Dynamite 
  • Collision grid is now 128x128 rather than 64x64
  • When an entity dies all his loop sounds are stopped
  • Entity sound emission center is also updated continuously
  • Sound code improved
  • Sound 3d is calculated more accurately
  • THBF now inherits from TObservableObject
  • New hero can duck
  • New element Darkness, darkness maps are only applied to background layers
  • New element Fluorescence
  • Now Explosions emit light
  • Now Nuclear emits light
  • Elements with no gravity are not affected by platforms (like boomerang)
  • New sound effects to be used: timeout, pitch, attenuation
  • Now sound system reuses a sound if same key and distance is lower
  • Too far away sounds are discarded
  • Playing a bit with sound occlusion
  • Now sounds can sleep and fade 
  • Now there is a generic way to store already taken objects
  • New TAchievementsHelper, all achievements code went there
  • Gamma is stored in config 
  • When Gatashi gets stuck then too many task calls to Bezier are made and music is interrupted, improved
  • Now enemies roar from time to time (playing with 3d sounds...)
  • Now lights are supported in the background layer 
  • Some solid blocks were disappearing  a frame before before being converted into an item
  • New element generic laser
  • Now shadows casting into walls are more optimized
  • New achievement "kill a fly"
  • New enemy turret 
  • Minimap refactored
  • Shadow diameter can be now set in realtime
  • New decorators in front layer (glass)
  • New interface IMinimap 
  • When a NPC is on a platform it goes away jumping


  • TSprite.Blit() reordered to do less IF/THEN/ELSE
  • Faster Blur() method
  • New TDummySprite.Move(x,y)
  • New TDummySprite.CollisionAt() it simulates a collision at X/Y 
  • Script property values are written using rtti
  • New property TSound.IsStarted 
  • TSurface2Poly optimized 
  • Improving the code that calls _intfclear
  • Using last version of BASS
  • New TLayer.CleanAttributes() and TLayer.CleanTiles()
  • New TVectorEx.Avg()
  • TAnimationSprite.Tick() and TDummySprite.Draw() improved a bit
  • New TObservableObject
  • TDummySprite now inherits from TObservableObject
  • New TSuperSprite helps to composite sprites 
  • New TAnimation.FileName
  • New TSound.Flags
  • TBasicCamera.Rotate() performance improved
  • TCollision performance improved
  • TSpriteEngine.Render performance improved
  • All single comparisons changed to TSingle(x).AsInt
  • TCollision hash key is no longer composed by strings but integers
  • TCollision minor performance improvements
  • TSprite minor performance improvements
  • New TCamera.ProjectVertexW when 1/Z is already calculated
  • Now TSprite caches W=1/Z, big performance
  • Quad effects and filter are done in the setter
  • TGraphicDriver.InView() performance improved
  • TGraphicDriver.DrawQuad() performance improved
  • Now TSprite.Z is TSprite.Priority and TSprite.DirectZ is TSprite.Z, both are combined to create the final Z
  • Sprite rotation coordinates are cached 
  • Now a MMX version of Fill32() is used
  • New TGraphicDriver.SetGammaRamp() to apply gamma (only fullscreen)
  • New fast Utils.Percent75
  • New THashMap<K,V>
  • New hashes for generic, 8, 32 and 64 bits sizes
  • Maps can now have blur
  • Events can be now grouped
  • Many float divisions changed to inverse mutiplications
  • Particles, float divisions avoided when possible
  • TScreen.DrawShape() improved not using FCapacity dictionary
  • New Cast<T>.Cast() 
  • New THashEx.Pack_Four()
  • Better performance in the D3D handling of buffers
  • New TMath.SinCos(), used when possible
  • Now maps can load extras that share same properties as []
  • Layer XShadow and YShadow are now floats

Sunday, October 7, 2018

HBF, experimental version

I've been playing for a while with the attribute [unsafe], the reason is that I use interfaces all over the code but I manage my own objects, so I don't need this COM overhead, I need basically interfaces behaving as clever pointers.

The game offers to all entities the following interface which returns many interfaces to handle any part of the game behaviour, like this nobody is aware of the implementations of the classes.

  IGameServices = interface
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetSession: ISession;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetEvents: IEvents;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetPlayers: IPlayers;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetCoins: ICoins;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetMap: IMap;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetDrawer: IGraphicDrawer;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetGraphicInfo: IGraphicInfo;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetLog: ILog;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetProfile: IProfile;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetFont: IFont;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetSmallFont: IFont;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetWindow: IWindow;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetLayer(aIndex: integer): ILayer;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetCameraHelper: ICameraHelper;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetHud: IHud;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetEffects: IEffects;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetSound: ISoundDispatcher;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetMusic: IMusic;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetFileSystem: IFileSystem;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetOptimizer: IOptimizer;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetFactory: ISpriteFactory;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetBack: IBackground;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetSettings: ISettings;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetHighscore: IHighscore;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetLevels: ILevels;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetVars: IMemVar;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetAchievements: IAchievements;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetRunes: IRunes;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetShop: IShopHandler;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetTimer: ICrono;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetInput: IInput;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetCurrentScreen: IScreen;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetTrigger: ITriggerDispatcher;
    {$IFDEF _UNSAFE_}[result: unsafe]{$ENDIF}function GetChat: IChat;

So a typical enemy would do GameServices.GetSound.Play() in order to play a sound.

GameSprite.pas.4293: begin
00A6BA50 53               push ebx
00A6BA51 56               push esi
00A6BA52 8BF2             mov esi,edx
00A6BA54 8BD8             mov ebx,eax
GameSprite.pas.4294: Exit(FGameServices);
00A6BA56 8BC6             mov eax,esi
00A6BA58 8B93A4030000     mov edx,[ebx+$000003a4]
00A6BA5E E8D5739AFF       call @IntfCopy
GameSprite.pas.4295: end;
00A6BA63 5E               pop esi
00A6BA64 5B               pop ebx

00A6BA65 C3               ret 

The classic IntfCopy() is there and of course their counterparts InfClear(). When you have a system which continuously passes interfaces then is quite an overhead.

In the experimental version we get:

GameSprite.pas.2834: result := GameServices.GetSound.Play(aFileName, aLoop, True);
00A63218 6A01             push $01
00A6321A 8BC6             mov eax,esi
00A6321C E863390000       call TGameSprite.GetGameServices

GameSprite.pas.4293: begin
00A66B84 51               push ecx
GameSprite.pas.4294: Exit(FGameServices);
00A66B85 8B80A4030000     mov eax,[eax+$000003a4]
00A66B8B 890424           mov [esp],eax
GameSprite.pas.4295: end;
00A66B8E 8B0424           mov eax,[esp]
00A66B91 5A               pop edx

00A66B92 C3               ret 

Hooray!, all that overhead is gone. The problem is that the compliler very often makes a mess and the code explodes as an AV (I haven't found a pattern), so I change the way the calls are done and then it no longer crashes.

For example this crashes (in some places of the code some others not):


changing the code  a bit as:

players := GameServices.GetPlayers;

Not a big deal but quite cumbersome to do all over the code, so I change it when it crashes.

Still not convinced?

Performance test with classic interfaces:

About 40 FPS for 50000 triangles.

Now with this UNSAFE stuff:

Almost 48 FPS for 50000 triangles.

I believe if worth the effort. It is important to note that interfaces should all be declared as const and never as inline.

So once I'm happy with the results I will publish this version.


Friday, October 5, 2018

Summer is gone...

Well, still not bad weather but summer "mode" is gone...

Anyway, as usual I always find time to improve the framework (which is the main idea behind all this) and the game itself.

Main changes are performance boost here and there, framework improvements, game stability and a new secret level.

Found binaries at OneDrive, here is the what's new:

  • All sounds are now played in 3d mode, panning and volume are continuously recalculated from hero
  • New class TChat 
  • Hero can sell items 
  • New class TColorTileHandler
  • Some lasers throw sparks when collide with a block
  • New trigger functions: IsDoorOpen(), SkipIfTrue() and SkipIfFalse()
  • Inventory had a memory leak, fixing that memory leak lead to many issues...
  • Now when throwing a weapon another one can be choosen and the old one still visible
  • Inventory now internally uses TStrings<T>
  • TShopHandler.Remove() is now faster 
  • Gift stuff removed, now they are invisible
  • Items now can also be sell
  • Shop/Inventory items code cleaned a bit
  • Platforms graviting was detecting itself...
  • Now when handling collision with blocks over a tape, tape speed is taking into account
  • New Headshot property distance 
  • New shop item Invisibility
  • All entities that could react to the presence of hero now take into account Invisibility
  • Teleport system rewrited, it was not handling properly the guests
  • Now boomerang distance is configurable
  • Shop shows information about items
  • New red boomerang (level 2)
  • Game now distinguish between vertical and horizontal slopes so everything is easier
  • Horizontal slopes take into account Facing property
  • Spider runs away when hero has immunity
  • New TSelf that reflects entities
  • New Mirror.Alignment property
  • Now arrow has a power = 1
  • Now stone has a power = 2
  • Now golden shield can stop lasers
  • Property Chest.Z changed
  • Left and Right collisions with slope tiles improved a bit
  • Now when shopping game shows the owned quantity of each item
  • A door can connect to other door from different level 
  • When connecting doors selection screen is not shown anymore
  • When selecting the next level, a sound is played
  • Now TLiquid implements IExecutor
  • Now Rotator can have different colors with ColorMaskA/B
  • Now rotator uses two light colors
  • Rotator now has a counter property so start Angle can be controlled
  • Now laser properly bounds in Mirrors
  • New class TFlyingEnemy
  • Now weapons can have a quantity (so bow does not have infinite arrows for instance)
  • Now Shop offers Ammo, a new shop item
  • Now any enemy can have wings and fly 
  • New aligments acBottomLeft and acBottomRight
  • Time shader off was not working
  • New Bomb bitmap
  • Now droid has a new laser color property 
  • New trigger CallElevator()
  • Trigger ItemOffset() renamed to TileOffset()
  • New trigger method MotionItem()
  • Unknown level is finished
  • Now teleport connection is per name and not per group, so teleports can freely connect to any teleport
  • Now Teleports can be disabled 
  • Now Teleports now can also handle enemies 
  • Door now can be closed automatically after open it with property CloseAfter
  • Door now can be half open but not accessible
  • Platforms can be executed from scripts 
  • Platforms bouncing adjusted at pixel level 
  • Now triggers and their timings are script dependent internally
  • Now weapons are used in grid collision matrix 
  • Improved code like "interface as TClass" with "TClass(interface.AsObject)" (seems to be faster)
  • Now when you get a coin you get a message with the number of coins 
  • Certain coins now use a Distributed Random Number Generator
  • Slots and Sounds per Slot are now configurable within the SoundDispatcher class
  • Sword cannot longer break walls, use bombs (hint...)
  • Extras code improved
  • New item property IsContinuous
  • Now monologue is now shown when in shop or inventory screen 
  • Graviting is done with walking animation
  • New inventory function ActivateOnlyOne()
  • Now inventory can be navigate it with up and down keys
  • Clear inventory was not working properly after the first game 
  • Fixed an issue pushing items recursively
  • In game menu now will always start with index 0 no matter how many times you access it
  • Now menus can be locked 
  • Now game fades properly when exiting game 
  • TBell renamed to TBells to avoid collision with extra.TBell 
  • Now triggers can have required items 
  • Countdown now has a direction property
  • Lamp has new style
  • Now game can be paused when fading
  • Fixed lamp light priority
  • TInventory.ActivateFirst() is now faster
  • Fixed error in magnet, when trying to read non IGameSprite interfaces and then AV
  • Map light is now blue
  • Pushable stuff now does slippery properly
  • GameServices.EnterInventory() moved to GameServices.GetPlayers.GetInventory.Enter()
  • GameServices.EnterShop() moved to GameServices.GetShop.Enter()
  • New TGameSprite properties MinAngle/MaxAngle to adjust the bounds of the gravity orientation 
  • TGameSprite.IsIce property removed (it was unused)
  • Countdown now uses Y for position
  • Spring weird movement fixed
  • Shield code moved to GameSprite 
  • Jumping force now uses property Power, so jumping enemies can have different jumping power 
  • TColumn can use now different sprite sets
  • Maximum camera zoom set to 1024
  • Fade step set to 4
  • Gravity orientation code refactored
  • Pushing objects use property Power 
  • Under some circumstances PushedByBlocks() got hero stuck
  • Shield can now stop fire bullets
  • Music timers are now local
  • Crepuscule is not a bit yellow
  • Now Pause key can also be redefined
  • When hero dies he also releases its chest keys
  • New class TRay
  • TCustomScreen refactored
  • Platforms can rotate with certain cadency
  • Game.GetTarget()/SetTarget() moved to CameraHelper
  • New trigger Sleep() (more complex than it sounds)
  • Ice can be sloped
  • Now any sprites supports multiple fellows
  • Now arrows can be called from the trigger system since they implement IExecutor
  • Shield and armor now takes into account hero's balance
  • Some maps now have floor traps in tiles
  • Fixed a bug when on top of ladder and jumping
  • New Scepter bitmap
  • New Explosion bitmap
  • Nulling some interfaces when destroying some entities
  • New helper Coins
  • New property TPlatform.SleepAfterBounce
  • Now message key can be set in the config 
  • Stalactite was not breaking when falling on top of a map item
  • Preparing screen code improved a bit
  • Gametrigger was not settting Script to nil when destroyed (AV)
  • Now there is a secret coins per map, jump to find it!
  • New TVanishPlatform
  • TRotatingPlatform fixed
  • Spring behavior improved
  • Top/bottom collisions are not checked when items are invisible
  • Left/Right collisions are done against rectangle and not BB
  • Liquid can now load any particle system
  • Now NEW_ATTRIBUTE is part of the non breakable attributes
  • New TFloatHelper.Abs(), faster by just clearing bit 31
  • Collition Matrix system improved a bit
  • TSurface.Blit(add) is now MMX 
  • New TRGB.Clamp() as MMX
  • Some buffer triangle functions writed as MMX
  • Now using TFloatHelper.Sqrt(), TFloatHelper.Trunc(), TFloatHelper.Round() which are MMMX optimized
  • Now TMatrixEx uses some MMX assembler optimizations
  • Now TVectorx uses MMX assembler optimizations
  • Removed inline from functions returning interfaces (Delphi makes a mess)
  • Removed inline when function result is string (bad optimization from compiler)
  • Cleaned functions that didn't need to be virtual
  • Sprite.Pause is no longer virtual (that was actually slowing down the game accoring to profiler)
  • New Sprite.CanPause property, useful when you want some sprites to never be paused
  • Improved sprite engine main loop by creating local vars of global vars and duplicating the loop with IF and not IF
  • New TObject.PopTag()
  • Now trigger calls must implement the Caller and script Name (this avoids some mess code)
  • New TLaser.CurrentSegments property 
  • For specific triangle routines Buffer.Tag is used rather than Shape.Tag
  • Now particles store the filename making debugging easier
  • New collection helper to sort as Insertion algorythm (good for almost sorted collections)
  • New YTLayer.GetCells() that works with map coordinates
  • TLayer.Trace() now works with map coordinates rather than pixel coordinates 
  • TSimpleSprite.CalculateQuad() reordered so that performance is improved
  • Fixed Z in Layer.AddItem()
  • TScript.RemoveWhenTaken removed, now use Counter = 1 (the default)
  • Now with RTTI system if enumerator does not exists an exception is raised
  • TEvents renamed to TEventEx
  • TEventEx loop forced to be forward (so calls order in scripts is respected, very important!)
  • TScript moved to its own unit
  • New LinkType property in triggers to allow more behaviors like mutual connexion
  • TStrings<T> is now used in TIni rather than TDictionary<K,V>
  • Scripts improved with TicksBetweenExecutions, Executor and Counter new properties
  • Distortions were not free properly
  • New TObjectEx.Error(), so that one does not need to do raise exception
  • TStateDirector<T>() improved a bit
  • Fading system improved a bit
  • property TSprite.FreeSurface removed (was always the negative of Cached)
  • Fixed a AV in Glow and Shadow surfaces  (double free)
  • Now when addings events if steps is zero then the CallBack is executed immediately
  • Fixed TMapInfo.HasTile(), my goodness...
  • Now script Input property can be any key
  • Fixed a silly typo error in collision library
  • New property TFont.Uppercase

Saturday, April 14, 2018

First 2018 update, it was about time...

I've been lazy lately, but that has to change, still from time to time I move my ass and code a little bit, this is the outcome:

  • Now game is paused, Shop, Inventory and Fight screens are substates, now code is cleaner and shorter
  • Curtain code cleaned
  • Now Shunenbukaidesu brings rain
  • Now when pause screen is gray
  • New TDirector code improved
  • Now Boom does some random rotations
  • Now Lights do some random zooming
  • New property TTriggerDispatcher.Player so code knows who did execute the trigger
  • TBell behavior improved
  • Backgrounds now can be setup in back.ini per level 
  • Now TGameSprite.Magnetized property
  • Now when adding a sprite to an engine it will enter the collision grid so that it can be search since the very beginning
  • UFO laser fixed (since when it was wrong? :)
  • New methods TGame.GameServices FadeIn(), FadeOut(), LockEntity() and LockExcept()
  • Left and Right collisions with moving objects improved
  • Now Dialogs have a Edit type so game can interaction can be done
  • Now game allows to add text (useful for chat)
  • Now Ropes can have different textures
  • New triggers IfItemThenSet(), RemoveItem(), ExecuteActionTile() and ExecuteActionEntity()
  • Now enemies can also activate triggers
  • Some levels now have a fourth layer (pipes and others)
  • Now TTriggerDispatcher has a Target reference (who did execute the trigger)
  • New trigger Velocity()
  • Pushed by blocks code fixed
  • New trigger Sleep()
  • Fade code refactored a bit
  • Fixed a bug in dialog system with NPC 
  • Extra Wand execution simplified
  • Now hero balance when standing
  • Added a new layer to all maps to handle better the trigger interactions
  • All layer are now declared as constants
  • Now circles shrink when interacting
  • Stalactite now works with gravity 
  • Graphics unused removed
  • Now game does Continuous Collision
  • Now Post is static
  • Now left/right collision with slope items/tiles works properly
  • Some fonts are shown with shadow
  • Collisions improved
  • New layer in the labyrinth
  • Owner property renamed to Hero
  • CarryItem property renamed to Owner
  • TGameSprite.IsUnderneathOf() fixed when gravity is up
  • Now music can fade in/out
  • Music now fades with screen
  • Now in mapping.ini one can assign directly the default animation, so for simple sprites there is no need to create a class 
  • Some new fonts
  • Now some level has a countdown...
  • New Door graphic
  • New wind effect
  • Notifications are now easier to code
  • New princess bitmaps

  • TStateMachine<T> renamed to TStateDirector<T>
  • TStateDirector<T> now supports substates as Push(T) and Pop(T)
  • Surface blur performance improved
  • TSurface Lightmap() performance improved
  • Many internal lists changed to TColony<T>
  • In TCollisionMatrix.Enter() Occupation was updated inside loops, that makes no sense and affects the performance
  • New classes TObjectColony<T> and TFastObjectPool<T>
  • INI class moved to its own file 
  • INI now uses internally TDictionary<K,V>
  • New TSprite.GetOldRectangle()
  • TCollisionMatrix performance improved
  • Particles now have a better management of internal textures
  • Now triggers have an Input property 
  • New TInput.ReadChar() so that game can read commands from user
  • Now triggers can only by executed by specific entity with property Holder/
  • Now Triggers can have Cadency, so the trigger can be only be updated every N Frames
  • Now triggers might have a Hint
  • Now triggers are called scripts
  • Now surfaces can have slopes left and right
  • TCollisionMatrix now checks for top/left and bottom/right corners
  • Now shadows are TBoolean rather than boolean
  • Now some fields are now TNullable<T>
  • Now map layers can have alpha configuration
  • Overhead with rotated matrix when angle = 0 reduced
  • Using [unsafe] tag when possible since my interfaces behave as pure interfaces with no reference counter
  • Now TTimerEx no longer uses an event but a callback
  • Some [UNSAFE] fixed
  • Many GUID removed from interfaces
  • Many const added to interfaces when parameter
  • New Glow properties color and blur  
  • New class TCountdown

Found binaries at OneDrive

Sunday, October 22, 2017

HBF can now be played on a LAN with up to four players!

Not because there are no news it means I'm doing nothing,  I was focus on net playing, not an easy topic, but as usual I love the concept "learning by doing", so this is the result of that process.

What's new in the game?

  • New unit Camera, all camera code moved from Game to new unit
  • New achievement "Finish the Labyrinth with a partner"
  • Now bat moves faster
  • TPlayerHandler.GetClosestHeroAt() fixed
  • When a platform is pushed, some particles are rendered
  • Stalactite has now some alpha
  • Fixed an issue with casting interfaces (suddenly it crashes...)
  • Mine now rotates a bit
  • Fixed offsets of lightmaps in darkness
  • Minimum resolution is 1024x768
  • All release inventory code moved from Game to Hero
  • Hero can have a partner on top of it
  • Monologues are now created on demand
  • Now when loosing a fight, owned runes are released, beware!
  • New Mine.Shake property
  • New trigger Follow()
  • New service GameService.GetEvents
  • When hero touches the ceil it liberates some Particles
  • Camera lerp enhancements to make the usage easier
  • Now Liquid might have a Tide
  • Rays colors changed in order to look better
  • Now Camera does all movements with interpolation, new method for lock/unlock
  • New Weapon properties Range and Quantity
  • Now Camera can focus any entity
  • New property TGameSprite.Triggers, so that any entity can execute any trigger/s
  • Doors can now be closed after being opened
  • Fixed an issue with the stalactite particles
  • New property Items.IsAutoso can be auto activated after they are taken
  • New triggers: AchievementDone(), ExecuteIfEqual(), ExecuteIfNotEqual(), KillAll() and Focus()
  • New Weapon.Maximum (as bullets)
  • New weapon Bow
  • Now extras can be automatic applied (like live)
  • Entities can execute triggers OnCreate, OnDestroy and OnTake
  • Monologues are delayed
  • Better Door states
  • Annoying bug changes have been fixed
  • Camera follows hero in a more stable manner
  • New inventory functions ActivateFirst() and Push()
  • New change action (to cycle weapons)
  • Snowball generates different particles than before
  • Items are not draw when exiting a level
  • Game can now be set to fullscreen/window at any time with Alt+Enter
  • Background also tries to adapt to camera Z
  • New Item.Detail property
  • Bell item sounds more continuous rather than per volume
  • New golden bow and golder arrow items
  • Arrow can have now an angle depending on how long the action button is pressed
  • Scores moved from inventory to players class
  • Map read cells event improved
  • When in shop background is rendered as sepia to make contrast
  • Entity.Excite() code refactored
  • HBF now can be played remotely (new menu option)
  • New host/port settings
  • New hero property Scope: local, remote
  • New dialog type Abort()
  • New level...
  • Better handling of network delayed games
  • TCPClient/TCPServer connected properties not used during game (seems they they corrupt network buffers)
  • Entities inside a thread/task using random functions will take a local Copy
  • Closing dialogs won't unlock the game if still locking pending messages
  • Better control of locked situations (visual messages VS waiting network)
  • New TNetBuffer PeakX()
  • New sound when hero is underwater
  • New item Water of Rhand
  • Menus now can show dialogs
  • Session id is send in every message, so client can refuse their own messages
  • Coins moved from inventory to TPlayerHandler class
  • TPlayerHandler refactored, now it is easier to follow the code
  • Dialogs, question can persist after callback
  • SessionId is send in all net messages so that clients can ignore messages at their own discretion
  • Terminal animation is different
  • Now input is in the form of K;J1;J2;J3
  • New screen Sync
  • Input read improved
  • New Hero.JoyId
  • Inventory moved to Players class
  • Stalactite now also also falls when top tile disappears
  • TCameraHelper.CoversAllPlayers() now does not take into account heroes that have already entered then door
  • New GameServices.GetImpersonateKeys()
  • Players iteration improved shorting edges (first/last)
  • Hero sessionId moved to Players class
  • New message to request the list of sessions
  • Now servers controls the maximum amount of players
  • Now game can be played with up to 4 players
  • Hero.Scope moved to Players class
  • New callback TPlayerHandler.GetPlayers()
  • New TPlayerHandler.MinPlayer() / TPlayerHandler.MaxPlayer()
  • Player removed from inventory
  • Added player Alias so when joining network games, players can be identified
  • New TPlayerHandler.FindPlayer(session)
  • New TNetBuffer Readstring & AddString, so now strings can me send in net protocol
  • if master leaves the game, then server finds a new master
  • New TPlayerHandler.GetSlots()
  • Game can now do multi-ping
  • NetworkPlayer concept removed (everything is in player and slots)
  • New TPlayerHandler.RemoveSlot()
  • More robust network control
  • Remote locks improved
  • New concept in network code channel (rq, all, target)
  • Max zoom improved
  • TPlayerHandler.GetDistance performance improved
  • Wand item now glows
  • Now when hitting enemies a white effect is done
  • Pushing moving blocks improved
  • When playing over net, camera focus on local player
  • Blind and Many players achievements are now configurable
  • New skin for player 2 (tough still ugly...)
  • Avoid Z players overlapping
  • Network locking simplified
  • Now HBF comes with a standalone server called GameServer.exe
  • Now dialogs are rendered correctly when title is short
  • Now network seed is taken from ticks and not from network, this makes the game more deterministic
  • Server now sends back the available slots
  • Network input is stored in a buffer so if we receive more than one packet all packages are processed in order
  • Reading joy process improved
  • Now game check if there is enough input devices
  • CheckPoint is back to Hero class
  • More control over disconnected sessions
  • Now TSpriteEngine uses TColony<T> as a main iterator class
  • Cannon had a AV when hero is dead
  • New THUd.Visible
  • New TPlayerHandler.RandomPlayer()
  • Now when entering Door a red flash is shown
  • When no lives and going to main menu, the in game menu will not be displayed
  • Falling controller is not always created by default
  • Some non used songs deleted
What's new in libraries?
  • DirectZ removed from sprite properties
  • Map does not longer creates a default camera
  • In TSpriteEngine.SpritesAt() there was an overloaded version that didn't use the spatial grid, speed boost!
  • Particles adaptive view fixed
  • TArrayEx<T>.Delete fixed
  • Object names are no longer used in release mode
  • Now maps have infinite loops again
  • Now sprite quads have a default Tag
  • TSpriteEngine.Find(name) was not working at all!
  • Maps now use frustum to check boundaries
  • Improving frustum in 2d maps rendering
  • New Map.FindTrigger()
  • New Trigger Context, so that engine knows when to execute the trigger (create,destroy,taken)
  • New buffer default size
  • New TPerspectiveCamera and TBasicCamera
  • Sprite engine searches are faster
  • New particles property RandomDirection
  • TInput now can keep track of now many frames a certain button was pressed
  • TSprite.SetAngle() now does not apply matrix if camera is not set
  • New inline TRGB _R(), _G(), _B() _A() and _32()
  • New laser aspect
  • Horizontal and vertical gradiants now take into account alpha channel
  • Blur() performance improved
  • TLayer now have a Glow property so that tiles can be glowed
  • New TRandomHelper useful for threads, otherwise random generators are corrupted and net game is not deterministic
  • Particles use their own random generator
  • TSurface.AverageColor() fixed
  • Now when creating Direct3D, flag D3DCREATE_FPU_PRESERVE is used
  • Many raise moved to their own function (performance)
  • Fixed a Lock() issue in TSound
  • New TParticles.IsSystemDown()
  • New classes TRingBuffer<T>, TSet<T> and TColony<T>
  • Now system can handle up to 4 gamepads
  • TInput improved
  • New TJoyData.JoyReleased()
  • Now levels are loaded with rtti
  • Triggers now can have a counter (executed when counter = 0)
  • Finally joy direction pressed are no longer simulated
  • Shadow and Glow helpers classes are not created by default
  • Queue particles are not created by default
  • Collection iterators improved

And that's all folks.

Saturday, April 29, 2017

HBF is not alone anymore, say hello to a new player.

Like a month ago I was thinking, why not add a second player?, but as usual new ideas bring new challenges.

Adding a second player to the game means many aspects of the game have to be modified, like who enters the Shop, how Items are split, some enemies need to decide the proper victim, how to handle when heroes are far away from each other, what do to when one die, change the behavior of the Door, who enters the Fight, rewrite most of the input system, etc.

That was as usual very funny. The most difficult part was to handle the Camera and order of sprites, so I decide so change the 2d engine to be more 3d (visually still the same), so now Camera can play with Z axis, then many Z issues appear..., so I had to revisit all game.

But anyway, the work is done after some tough weeks :-)

Found binaries at OneDrive
  • Now two players can play the game, big improvement
  • Now when a coin is taken it executes a different particle
  • Now levels starts differently
  • Item cross code improved
  • Sprite.AttachedSprite code improved
  • New emerge particle
  • Now Focus element blinks
  • New FadeIn() styles
  • New HUD layout
  • Keys code is now handled directly in the inventory class
  • Now checkpoints are handled in the player class
  • Camera now needs to cover correctly all situations (when one hero dies and checkpoint cannot be covered by camera when in two players, etc)
  • Now doors still closed when taking the key and can only be opened by the owner of the key
  • When in two players, if one player looses of lives, then he releases all inventory so that the other player can take it
  • When in two players, if one player looses of lives and the other player has already entered the door, then the level finishes
  • Input reading code optimized
  • Now Fight, Shop and Inventory can only be used by the player that activate it
  • Shop/Inventory/Items code improved
  • Fight changed a bit
  • New heart item
  • New class TPlayers
  • New extra TPresent
  • New EntityType Magma
  • Scepter is no longer spawned in Lava
  • If hero looses the Rune Fight he also looses his coins
  • Now when finishing level, camera focus and zoom on Door
  • Now aspect ratio can be selected (4:3, 19:9, 16:10), so game should fit properly with all resolutions
  • Camera Lerp now also takes into account Z
  • Drawing air moved from hero to HUD
  • Now heroes are able to push many blocks in a row either vertical or horizontal
  • Some interfaces were not set to nil on destroy

  • Doing a render to target and losing the surfaces does not work, it raises an AV, why?!
  • Sleep properties in Particles now talk about milliseconds rather than steps
  • Lightmaps now also interpolate alpha channel
  • Some internal array improvements (aligned to next power of two)
  • Surface.Blur() quality improved
  • TArrayEx<T> improved
  • Now the 2d engine is completely dine in 3d, so that one can freely play with the camera
  • Fonts performance improved
  • New TCamera2D.Rotate()
  • Shadow silhouette improved (a bit of blur applied)
  • New TMenu.Find() in order to find menu items and optionally be able to modify them
  • New events for particles OnBefore/OnAfter Create/Tick
  • gamepad set to DISCL_NONEXCLUSIVE

New aspect ratio option)

 HBF now is accompanied by his partner ABB (say what?)

Camera zoom out to fit both players (until a certain point)