Skip to content

Extending

Nill edited this page Jun 30, 2021 · 1 revision

This page entails the various ways you might want to extend the game and what that might entail.

Graphics

16x16 Tile Graphics

The standard tile graphics are stored in /Content/blocks.bmp, there are two unused tiles, if you need more you can simply extend the image vertically in 16px increments.

After you update this bitmap, give your tile a name by adding it to the Tile enum in Assets.cs.

8x8 Font Graphics

The 8x8 graphics used for text and other small symbols is stored in /Content/text.bmp. The first 6 rows of 8x8 tiles can be used for the characters in the character set.

Add the character mapping in the appropriate spot in Assets.BuildFont() in Assets.cs and then use that character anyplace a string is being drawn.

8x16 Scroll Icons

To add new scroll inventory icons, edit /Content/text.bmp and use the spare slots in the bottom row. Do not touch the last 3 slots on the row (empty slot, torn end, tip of scroll)

Define which items map to which icons in Level.RenderScroll() in Level.cs.

Animations

Animation scripts are stored in the Animation struct in Animation.cs. Simply create a static instance.

The first parameter is the number of ticks each frame is shown for (e.g. speed with 1 being the fastest).

The remainder of the parameters are the list of Tile's in the order to play them; if the animation should does not loop or needs to trigger an event when finished, use the Tile.AnimationEnd constant.

You can OR a Tile value with one of the following commands:

        FlipXon = 0x10000,      // Turn on H mirror
        FlipYon = 0x20000,      // Turn on V mirror
        FlipXoff = 0x40000,     // Turn off H mirror
        FlipYoff = 0x80000,     // Turn off V mirror

Example:

public static Animation Tongue = new Animation(2, Tile.Tongue, 
        Tile.Tongue2, Tile.Tongue, Tile.Tongue3, Tile.Tongue2, Tile.AnimationEnd);

Use the animation by setting the Animation property of an object to the new struct value.

Cells

To use a tile in the cell grid, add a value to the Cell enum in Cell.cs.

  • By default the enum value in Cell should match the same value from Tile.
  • If the cell needs special logic, you can override this in Layout.CellToTile() in Layout
  • Do not use enum values higher than 0xFFFF, as the high word of the Cell dword is the modifier value.

By default all cells are collectible items unless they pass the IsSolid() check, so if your cell is intended to be a background/decoration/passive element, modify Layout.IsItem() to return false for your cell type.

Terrain

To give a cell (see above) specific properties, modify the appropriate function based on how you want the block to react:

  • Layout.IsSolid() - Whether solid for Dana and enemies
  • Layout.IsEmpty() - Whether Dana can create a break here
  • Layout.IsConcrete() - Whether or not concrete collision checks apply (alt sparky)
  • Layout.IsSolidNotMesh() - Same as IsSolid but excludes drainage tile-like blocks
  • Layout.IsBreakable() - Whether or not Dana/enemies can break this block
  • Layout.IsBreakableWitHead() - Whether or not Dana can break with head
  • Layout.IsSpreadBreak() - Whether or not breaking this block cascades to adjaent cells of similar type

Items

  • Any cell that returns true from Layout.IsCell() is collectible.
  • Modify Dana.GiveItem() to control what happens when Dana collects it.

Other item-related tests:

  • Layout.IsShrine() - Is cell a shrine? Adds to inventory and triggers bonus room.
  • Layout.IsSeal() - Is the cell a seal? Adds to inventory.
  • Layout.IsCartouche() - Is the cell a cartouche? Adds to inventory.
  • Layout.IsDense() - Determines if an item prevents a block from being broken from below like keys and doors.
  • Layout.IsKeyAtAll() - Determines if an item is treated as a key (can have a KeyInfo assigned)
  • Layout.IsDoorAtAll() - Determines if an item can be treated as a door (can have a DoorInfo assigned)

Enemies / Objects

To create a custom object, create a class and inherit GameObject. Override any of the applicable functions to implement your game logic.

To make it available in the editor, add it to the ObjType enum, and ensure that the value of LastEditorValue is equal or greater than the value of your object in the enum. (Values after this are not selectable in the editor).

Add your type to the GameObject.Create() function in GameObject.cs and also give it a frame for the editor by adding it to LevelEditor.GetObjTile(). To control what speeds, flags, directions it supports, edit EditorMode.FixFlags()

Sound and Music

To add sounds, add them into the MonoGame content pipeline (Content.mgcb) as a "MonoGame - Sound Effect" type.

Add a property to the Sound class in Sound.cs (where it says 'add new sounds/music here'), and load it in Sound.LoadSounds(). See the existing sounds for examples of how they're set up.

To make music accessible in the editor, assign it a numeric value in Level.InitMusic() and then, if needed, edit LevelMode.editMusic() to ensure the editor allows you to select that high of a number.

Something Else

Implement anything you want, bonus games, side games, config screens, alternate editors, by inheriting the World class and then using Game.SwitchMode() to switch to an instance of your world. You will then get Init(), Render(), and Update() calls to do everything you need.

Clone this wiki locally