Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Quicksand 1.20

Quicksand Version: 1.20
By: Glitchfinder


Introduction

Glitchfinder's Quicksand script implements a feature most people have wanted, but few have managed: quicksand in RMXP. The quicksand has adjustable sinking speeds, and you die if you stay completely submerged for too long. To top it all off, the deeper you are, the slower you move. Excellent for use in deathtrap puzzles and the like.

Features
  • Adds quicksand!
  • The player actually sinks into the ground!
  • The player dies if they can't get out!
  • The deeper the player is, the slower they move!
  • The player pops out of the ground if they manage to escape the quicksand!
  • Easy debugging!

Screenshots

I have a screenshot, and I might actually make a video if I can be bothered to reinstall my screen capture software and configure it again.

Quicksand.png


Script

Here's the script, but I recommend you try to demo to get an idea of how it works.
Code:
#≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡

# ** Team Scriptastic's Quicksand                                [RPG Maker XP]

#    Version 1.20

#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

#  This script adds quicksand that a player can sink into and die.

#==============================================================================

# * Version History

#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

#   Version 1.00 ------------------------------------------------- (2009-08-08)

#     - Initial Version

#     - Author: Glitchfinder

#    Version 1.10 ------------------------------------------------ (2009-08-15)

#      - Added maximum depth

#      - Modified player speed to slow character when sinking.

#      - Author: Glitchfinder

#    Version 1.20 ------------------------------------------------ (2009-08-16)

#      - Added debug code to print tile ID that the player is standing on.

#      - Author: theory

#==============================================================================

# * Instructions

#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

#  Place this script above Main, and below the default scripts. (I realize this

#  is obvious to most, but some people don't get it.)

#  

#  This script requires an intermediate level of scripting experience to use.

#  Setup takes place inside the Scriptastic class located immediately following

#  this header.

#  Quicksand.default - Don't touch this one.

#

#  Quicksand[(tileset filename)] = {

#     'tile_ids' => [##],

#     'speed' => [##],

#     'autotiles' => [##],

#     'autotile_speeds' => [##],

#     'game_over' => [(true or false)]

#  }

#

#  'tile_ids'

#  Replace tile_ids ## with the tile ID of the tiles you would like to have a

#  quicksand effect.  While not a simple task, we have attempted to make it as

#  easy as possible by including a simple utility method for you.

#  You can "Call Script..." on any event, and enter "print_tile_ids".

#  This will display a window with the tile IDs for the tile on each of the

#  three layers.

#  To make matters easier, I added a button for this.  Press F5 while in debug

#  mode to display the tile IDs where the player stands for all three layers.

#  If this button collides with another script configuration, simply

#  change the Input.trigger?(keycode) command in Scriptastic.quicksand_debug .

#  Enter the tile ID of the desired tile(s) in the tile_ids array, seperated by

#  commas if using more than one tile.

#

#  'speed'

#  Replace the ## in speed with the number of frames it takes to reach the

#  fully buried (game_over, if applicable) state.  Number of frames implies

#  that lower numbers will be faster, while higher numbers will be slower.  The

#  actual sinking speed is a percentage of the bitmap height of the character,

#  so larger events will sink faster than lower events, though it will bear the

#  same time limit (same number of frames) they have to make it across (out)

#  before becoming completely buried.

#  Note that if you used more than one tile, these speeds will have to be

#  entered in the same manner, comma seperated, and in THE EXACT SAME ORDER,

#  even if they are all the same speed.

#

#  'autotiles'

#  Similar to tile_ids, this is used to assign a quicksand effect to autotiles.

#  The autotile id is much simpler, however, as its defined by the order they

#  appear in the top row of the tileset in the editor.  Note that the blank

#  tile at the left counts as '0', and cannot be assigned a quicksand effect.

#  The top row of tiles (eight across) would look like this: 0,1,2,3,4,5,6,7 .

#  Enter them in the same manner as tile_ids, comma seperated if assigning a

#  quicksand effect to more than one autotile.

#

#  'autotile_speeds'

#  This is the same as 'speed', only the order applies to (and must reflect)

#  the 'autotiles' array rather than the 'tile_ids' array.  Again, make sure

#  your entries are in the same order as the autotiles for proper operation.

#

#  'game_over'

#  For each tileset, this is either true or false.  If it's true, the player

#  will reach a game_over screen a few seconds after becoming completely buried.

#  If set to false, the player will simply be inhibited, and not killed as a

#  result of being buried.

#

#

#  If you are having trouble with this script, double check your tile ids, and

#  make sure you have the same number of tile_id's (or 'autotiles') as you do

#  entries for 'speed' and 'autotile_speeds'.

#==============================================================================

# * Method List

#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

#  Game_Character

#

#  print_tile_ids

#    Prints the tile ids of the tiles under the character, in order from the

#    first layer to the third. Called by the Interpreter's print_tile_ids()

#    method.

#

#  Interpreter

#

#  print_tile_ids(character)

#    prints the id of all tiles under the specified character. The character

#    variable can be -1 for the player, 0 for the current event, or a higher

#    number for the event whose ID it matches.

#==============================================================================

# * Usage

#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

#  This script may be used with the following terms and conditions:

#

#    1. This script is free to use in any noncommercial project. If you wish to

#       use this script in a commercial (paid) project, please contact

#       Glitchfinder at his website.

#    2. This script may only be hosted at the following domains:

#         [url=http://www.glitchkey.com]http://www.glitchkey.com[/url]

#         [url=http://www.hbgames.org]http://www.hbgames.org[/url]

#    3. If you wish to host this script elsewhere, please contact Glitchfinder.

#    4. If you wish to translate this script, please contact Glitchfinder. He

#       will need the web address that you plan to host the script at, as well

#       as the language this script is being translated to.

#    5. This header must remain intact at all times.

#    6. Glitchfinder remains the sole owner of this code. He may modify or

#       revoke this license at any time, for any reason.

#    7. Any code derived from code within this script is owned by Glitchfinder,

#       and you must have his permission to publish, host, or distribute his

#       code.

#    8. This license applies to all code derived from the code within this

#       script.

#    9. If you use this script within your project, you must include visible

#       credit to Glitchfinder, within reason.

#≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡

 

module Scriptastic

  def self.quicksand_debug

    return Input.trigger?(Input::F5)

  end

  Quicksand = {}

  Quicksand.default = {

    'tile_ids' => [], 

    'speed' => [], 

    'autotiles' => [],

    'autotile_speeds' => [], 

    'gameover' => false

  }

  Quicksand['007-Swamp01'] = {

    'tile_ids' => [], 

    'speed' => [],

    'autotiles' => [5, 6, 7], 

    'autotile_speeds' => [240, 160, 120],

    'gameover' => true

  }

end

 

#==============================================================================

# ** Scene_Map

#------------------------------------------------------------------------------

#  This class performs map screen processing.

#==============================================================================

 

if $DEBUG  # Only load this ID check hack if in $DEBUG mode.

  class Scene_Map

    alias scriptastic_quicksand_scene_map_update update

    def update

      if Scriptastic.quicksand_debug

        $game_system.map_interpreter.print_tile_ids(-1)

      end

      scriptastic_quicksand_scene_map_update

    end

  end

end

      

#==============================================================================

# ** Game_Character (part 1)

#------------------------------------------------------------------------------

#  This class deals with characters. It's used as a superclass for the

#  Game_Player and Game_Event classes.

#==============================================================================

 

class Game_Character

  #--------------------------------------------------------------------------

  # * Public Instance Variables

  #--------------------------------------------------------------------------

  attr_reader   :quicksand_height         # ID

  #--------------------------------------------------------------------------

  # * Alias Methods

  #--------------------------------------------------------------------------

  alias scriptastic_quicksand_game_character_initialize initialize

  alias scriptastic_quicksand_game_character_update update

  alias scriptastic_quicksand_game_character_move_type_custom move_type_custom

  #--------------------------------------------------------------------------

  # * Object Initialization

  #--------------------------------------------------------------------------

  def initialize

    scriptastic_quicksand_game_character_initialize

    @quicksand_height = 0.00

    @old_name_quicksand = ''

    @original_move_speed = @move_speed

  end

  #--------------------------------------------------------------------------

  # * Frame Update

  #--------------------------------------------------------------------------

  def update

    scriptastic_quicksand_game_character_update

    if @old_name_quicksand != @character_name

      bitmap = RPG::Cache.character(@character_name, @character_hue)

      @quicksand_height = bitmap.height / 4

      @old_name_quicksand = @character_name

    end

  end

  #--------------------------------------------------------------------------

  # * Move Type : Custom

  #--------------------------------------------------------------------------

  def move_type_custom

    # Interrupt if not stopping

    if jumping? or moving?

      return

    end

    # Loop until finally arriving at move command list

    if @move_route_index < @move_route.list.size

      command = @move_route.list[@move_route_index]

      if command.code == 29

        @original_move_speed = command.parameters[0]

      end

    end

    scriptastic_quicksand_game_character_move_type_custom

  end

  #--------------------------------------------------------------------------

  # * Print Tile IDs

  #--------------------------------------------------------------------------

  def print_tile_ids

    tile_ids = []

    for i in 0..2

      tile_ids.push($game_map.data[@x, @y, i])

    end

    x = @x.to_s

    y = @y.to_s

    s = "The currently specified coordinates are (" + x + ", " + y + ").\n\n"

    s += "The tile ID of layer one is " + tile_ids[0].to_s + ".\n"

    s += "The tile ID of layer two is " + tile_ids[1].to_s + ".\n"

    s += "The tile ID of layer three is " + tile_ids[2].to_s + ".\n"

    print s

  end

end

 

#==============================================================================

# ** Game_Player

#------------------------------------------------------------------------------

#  This class handles the player. Its functions include event starting

#  determinants and map scrolling. Refer to "$game_player" for the one

#  instance of this class.

#==============================================================================

 

class Game_Player < Game_Character

  #--------------------------------------------------------------------------

  # * Alias Methods

  #--------------------------------------------------------------------------

  alias scriptastic_quicksand_game_player_update update

  #--------------------------------------------------------------------------

  # * Frame Update

  #--------------------------------------------------------------------------

  def update

    scriptastic_quicksand_game_player_update

    quicksand_data = Scriptastic::Quicksand[$game_map.tileset_name]

    quicksand = false

    for i in [2, 1, 0]

      tile_id = $game_map.data[@x, @y, i]

      autotile_id = 0

      if tile_id >= 48 && tile_id <= 383

        if tile_id >= 48 && tile_id < 96

          autotile_id = 1

        elsif tile_id >= 96 && tile_id < 144

          autotile_id = 2

        elsif tile_id >= 144 && tile_id < 192

          autotile_id = 3

        elsif tile_id >= 192 && tile_id < 240

          autotile_id = 4

        elsif tile_id >= 240 && tile_id < 288

          autotile_id = 5

        elsif tile_id >= 288 && tile_id < 336

          autotile_id = 6

        else

          autotile_id = 7

        end

      end

      if (quicksand_data['tile_ids'].include?(tile_id) ||

        quicksand_data['autotiles'].include?(autotile_id)) &&

        @quicksand_height >= 1

        index = quicksand_data['tile_ids'].index(tile_id)

        if index == nil

          index = quicksand_data['autotiles'].index(autotile_id)

          speed = quicksand_data['autotile_speeds'][index].to_f

        else

          speed = quicksand_data['speed'][index].to_f

        end

        @quicksand_height = (@quicksand_height * (speed - 1.00)) / speed

        if @quicksand_height.truncate == 0 && quicksand_data['gameover'] == true

          $scene = Scene_Gameover.new

        end

        quicksand = true

        break

      end

    end

    bitmap = RPG::Cache.character(@character_name, @character_hue)

    percent = @quicksand_height / (bitmap.height / 4)

    @move_speed = (@original_move_speed * percent).to_i

    @move_speed = 1 if @move_speed <= 0

    @move_speed

    unless quicksand == true

      if @quicksand_height > bitmap.height / 4

        @quicksand_height = bitmap.height / 4

      elsif @quicksand_height < bitmap.height / 4

        @quicksand_height = (@quicksand_height * (11.00)) / 10.00

      end

    end

  end

end

 

#==============================================================================

# ** Sprite_Character

#------------------------------------------------------------------------------

#  This sprite is used to display characters. It observes a instance of the

# Game_Character class and automatically changes sprite conditions.

#==============================================================================

 

class Sprite_Character < RPG::Sprite

  #--------------------------------------------------------------------------

  # * Alias Methods

  #--------------------------------------------------------------------------

  alias scriptastic_sprite_popup_sprite_character_initialize initialize

  alias scriptastic_sprite_popup_sprite_character_update update

  #--------------------------------------------------------------------------

  # * Object Initialization

  #     viewport  : viewport

  #     character : character (Game_Character)

  #--------------------------------------------------------------------------

  def initialize(viewport, character = nil)

    @height = nil

    scriptastic_sprite_popup_sprite_character_initialize(viewport, character)

  end

  #--------------------------------------------------------------------------

  # * Frame Update

  #--------------------------------------------------------------------------

  def update

    scriptastic_sprite_popup_sprite_character_update

    if @quicksand_height != @character.quicksand_height

      rect = self.src_rect

      y_offset = rect.height - @character.quicksand_height.truncate

      self.y += y_offset

      self.src_rect.height = @character.quicksand_height.truncate

      @quicksand_height = @character.quicksand_height

    end

  end

end

 

#==============================================================================

# ** Interpreter

#------------------------------------------------------------------------------

#  This interpreter runs event commands. This class is used within the

#  Game_System class and the Game_Event class.

#==============================================================================

 

class Interpreter

  def print_tile_ids(character)

    chara = get_character(character)

    chara.print_tile_ids if chara != nil

  end

end

Demo

You can download the demo here

Instructions

Place this script above Main, and below the default scripts. (I realize this is obvious to most, but some people don't get it.)

This script requires an intermediate level of scripting experience to use. Setup takes place inside the Scriptastic class located immediately following this header.

Code:
Quicksand.default # Don't touch this one.

 

Quicksand[(tileset filename)] = {

  'tile_ids' => [##],

  'speed' => [##],

  'autotiles' => [##],

  'autotile_speeds' => [##],

  'game_over' => [(true or false)]

}

'tile_ids'
Replace tile_ids ## with the tile ID of the tiles you would like to have a quicksand effect. While not a simple task, we have attempted to make it as easy as possible by including a simple utility method for you. You can "Call Script..." on any event, and enter "print_tile_ids". This will display a window with the tile IDs for the tile on each of the three layers.

To make matters easier, I added a button for this. Press F5 while in debug mode to display the tile IDs where the player stands for all three layers. If this button collides with another script configuration, simply change the Input.trigger?(keycode) command in Scriptastic.quicksand_debug. Enter the tile ID of the desired tile(s) in the tile_ids array, separated by commas if using more than one tile.

'speed'
Replace the ## in speed with the number of frames it takes to reach the fully buried (game_over, if applicable) state. Number of frames implies that lower numbers will be faster, while higher numbers will be slower. The actual sinking speed is a percentage of the bitmap height of the character, so larger events will sink faster than lower events, though it will bear the same time limit (same number of frames) they have to make it across (out) before becoming completely buried.

Note that if you used more than one tile, these speeds will have to be entered in the same manner, comma separated, and in THE EXACT SAME ORDER, even if they are all the same speed.

'autotiles'
Similar to tile_ids, this is used to assign a quicksand effect to autotiles. The autotile id is much simpler, however, as it's defined by the order they appear in the top row of the tileset in the editor. Note that the blank tile at the left counts as '0', and cannot be assigned a quicksand effect. The top row of tiles (eight across) would look like this: [0,1,2,3,4,5,6,7] . Enter them in the same manner as tile_ids, comma separated if assigning a quicksand effect to more than one autotile.

'autotile_speeds'
This is the same as 'speed', only the order applies to (and must reflect)
the 'autotiles' array rather than the 'tile_ids' array. Again, make sure your entries are in the same order as the autotiles for proper operation.

'game_over'
For each tileset, this is either true or false. If it's true, the player will reach a game_over screen a few seconds after becoming completely buried. If set to false, the player will simply be inhibited, and not killed as a result of being buried.

If you are having trouble with this script, double check your tile ids, and make sure you have the same number of 'tile_ids' (or 'autotiles') as you do entries for 'speed' and 'autotile_speeds'.

Method List

Mouse.update

Updates mouse input. Calls to this method are not necessary unless the default Input module is not being updated.

Game_Character

print_tile_ids

Prints the tile ids of the tiles under the character, in order from the first layer to the third. Called by the Interpreter's print_tile_ids() method.

Interpreter

print_tile_ids(character)

Prints the id of all tiles under the specified character. The character variable can be -1 for the player, 0 for the current event, or a higher number for the event whose ID it matches.

Terms and Conditions

  • This script is free to use in any noncommercial project. If you wish to use this script in a commercial (paid) project, please contact Glitchfinder at his website.
  • This script may only be hosted at the following domains:
    http://www.glitchkey.com
    http://www.hbgames.org
  • If you wish to host this script elsewhere, please contact Glitchfinder.
  • If you wish to translate this script, please contact Glitchfinder. He will need the web address that you plan to host the script at, as well as the language this script is being translated to.
  • The script header must remain intact at all times.
  • Glitchfinder remains the sole owner of this code. He may modify or revoke this license at any time, for any reason.
  • Any code derived from code within this script is owned by Glitchfinder, and you must have his permission to publish, host, or distribute his code.
  • This license applies to all code derived from the code within this script.
  • If you use this script within your project, you must include visible credit to Glitchfinder, within reason.
 

regi

Sponsor

Cool stuff! I remember I used to want one of these scripts. It's a great concept, one I'm sure will add some depth to regular old dungeon exploration.

Perhaps an improvement on eye-candy would be sprite transparency (akin to the bush flag), rather than just cutting the sprite off at the head. That would give the illusion that a character is actually sinking under..sand.
 
regi":13jamj0f said:
Cool stuff! I remember I used to want one of these scripts. It's a great concept, one I'm sure will add some depth to regular old dungeon exploration.

Perhaps an improvement on eye-candy would be sprite transparency (akin to the bush flag), rather than just cutting the sprite off at the head. That would give the illusion that a character is actually sinking under..sand.

Thanks for the comment. As for the sprite transparency thing, it's a bit tough to explain. I toyed with the bush flag when I was making this, and partway through, I realized what was bugging me about it. Quicksand isn't so much water as it is dirt and soil that is so full of water that it can't support your weight. It's still opaque, like dirt and soil, and it amounts to a pit of mud. I might update this sometime in the future to use the bush flag to blur the character out over two or so pixels rather than making it into a sharp change, though. It depends on how that looks when I try it, I suppose.
 
I really like this... I told you before I love the idea, and that I haven't really seen it before in a game knowingly (even though I played GS2... but I'm still puzzled on where it should've been XD ).

The execution is done quite well, however the graphic style of RMXP kinda destroys it (with the feet at the bottom of a tile, and all...). That leads to lots of occasions where you think you can walk to the left or right to save yourself, while you really can't, because you're one tile higher. Actually, your demo map is an excellent demonstration for this effect as well. I took the time to travel on every spot reachable, and I had quite a few problems doing so. Obviously, that's not the fault of your script, and can easily be fixed by using different sprites. For example, this should look awesome with RO or VX sprites really.

The other problem I got with it is the player guidance aspect upon when the player is sub-travelling. The cheap solution is showing an arrow or something over the player, but yeah... that's quite FFVII-ish. The cooler thing would probably be - while unrealistic - popping bubbles or whatever. That way, you could also show "drowning progress", however that might be a bit advanced. Either way... as soon as I'm under the mud, I don't know where my character is anymore. That might be realistic, but I think from a game design point of view, the unrealistic approach is the better one... maybe?

That being said, I really like the concept and execution of this. And it'S nice to see some older work you did :)
 
This is great. Well, to be honest, anything that lets people create cool and complex puzzles is good in my books. But nicely executed too.
 
SpectrumGirl":mp77i0hn said:
Hey. Is it possible to make the character stop sinking at a certain point?

It would be, with an edit to the script. At the moment, all I have included is a sinking speed for each tile.

Also, thank you como!
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top