Menu system mouse implementation for the default scripts

posted Nov 13, 2011, 3:15 AM by Zeriab NA

I cleaned up my event-driven mouse implementation in the default scripts I presented a long time ago. You can download the demo here: http://www.mediafire.com/?igqjhk8h01y2a2h
This does not add any functionality to click on the map except choices in the message window.

I will not present a modular script since this is highly integrated into the default scripts. Instead I have tried a different concept where I have placed all the copy-paste code just above main. (Except my attr_sec_reader and F12 fix, the latter which must be the first section)
I have marked the default script sections I have edited with a * in front of it's name. In those sections I have tagged the code I have removed with <REMOVE> using comment blocks and I have tagged the code I have added with <ADD> and </ADD>.
I could have been more precise showing more exactly what I have added/removed with my code tags but I decided to only doing whole line add and removal as that's easier understand.
Here is an example:

   if Input.trigger?(Input::C)
=begin  <REMOVE>
      # If equipment is fixed
      if @actor.equip_fix?(@right_window.index)
        # Play buzzer SE
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      # Play decision SE
      $game_system.se_play($data_system.decision_se)
      # Activate item window
      @right_window.active = false
      @item_window.active = true
      @item_window.index = 0
=end
      ##  <ADD>
      right_trigger
      ##  </ADD>
      return
    end

You can remove the code tags if you want. It is after all just comments. I do think having them makes it easier to understand both what code I have touched and why. In this case I refactored the removed code into the right_trigger method which I then can easily call with the right mouse event.

With my script you will have to custom script the mouse functionality to most interactive menu customization. That is a cost of using this script. On the bright side you get more stability and are able to distinguish between clicking left clicking and pressing enter. (A common mistake by other mouse implementations I have seen. I don't really know why though)

*hugs*

F12 Proper Reset (XP/VX)

posted Sep 11, 2010, 6:31 AM by Zeriab NA   [ updated Sep 11, 2010, 6:42 AM ]

I just found this script by Bulletxt which abuses my butt-ugly $f12_cleaner_F3XXEFA1 from my previous F12 reset script. Yay for incompatibility -_-
I highly recommend that you do not try using the two scripts together.

Anyway I had a look at it and decided to revise it: http://paste-bin.com/view/0e59aa30
This time the testplay debug mode will not be lost.

Oh, and this script is compatible with both XP and VX.
I highly suggest that you insert a section at the very top and paste the script there.

*hugs*

Always in center + black edges

posted Sep 7, 2010, 3:25 PM by Zeriab NA   [ updated Sep 8, 2010, 11:51 AM ]

Here is a little XP snippet I made which make sure that the player is always centered. Black edges are added border of the map: http://paste-bin.com/view/e365a0f9

I made a VX version which makes parallaxes stretch to the borders: http://paste-bin.com/view/d37d8447

*hugs*

Checking map transfers

posted Sep 6, 2010, 6:22 AM by Zeriab NA   [ updated Sep 7, 2010, 8:37 AM ]

Here is a little ugly script which goes through all map and common events in the project checking the map transfers.

XP: http://paste-bin.com/view/3fc3d6c6
VX: http://paste-bin.com/view/0e59681e

Usage:
Copy and paste the script as the very first thing in the script editor.
Run the game. It should close after some time producing an out.txt file.
Delete the script again (so you can actually play the game).

This text file contains a list of maps you never transfer to. (If you use saves from a previous game they could easily end up here ^^)
A list of maps which there are transfers to, but which does not exist in the project. Each map id is accompanied by an array of map events (map_id:event_id) and common events (common_event_id) which has the transfer to the non existing map.

*hugs*

Reading F1 controls

posted Jun 1, 2010, 4:55 AM by Zeriab NA   [ updated Apr 26, 2011, 11:02 PM ]

Here is a snippet which displays how you can read which controls have been entered through F1: http://pastebin.com/jQeJXLSF
Currently it disables gamepad controls. Anyone can feel free to merge it into their own work or use it as it is. (If you have gamepad troubles for any reason)

http://pastebin.com/KZyTS6cB

Unfinished stuff

posted Apr 21, 2010, 3:04 PM by Zeriab NA

As I will leave for a long time I have decided to upload a bunch of unfinished stuff I have worked on. It's very unlikely that I'll finish any of them, so I thought I might as well make it possible for others to use and build upon the stuff if they want. They can all be retrieved from this mediafire folder. You'll find a short description of each below.

You are allowed to use anything I have made for any of these items for commercial and non-commercial projects alike except where explicitly otherwise mentioned.

FunFun
A game I played around with several years ago. It turned into a script testing ground rather than a game. Eventually I forgot about it.

ComboSystem
The relics of a system I made back when I was in the Gold Team guild in RMRK.
I abandoned it and didn't bother to try and solve its problems.

RGSS
The idea is to allow RGSS library methods to be used in auto-completion and etc. in IDEs which for example could be Eclipse.

Poker
I started making a poker system based upon Trickster's Card Library. I believe credits goes to EiB, Tana and Wumpi for the cards. I don't know for which cards.
The PokerTest is a stress test of the two update schemes. I remember something about the Update_Scheme_Fast either being slower or insignificantly faster. Considering how ugly it looks it should probably just be removed.
Note that the license of the resources I use is not under my control. You are free to use the parts I have made.

ZCSLS
A custom save/load system I made for a scripting contest back in November 2006.

ZWSTechDemo
A tech demo I made for a window system I once worked on. Some of the tests are stupidly multithreaded and there are game crashing race conditions present.
I remember the system as being a bit too elaborate and having some thight coupling problems. This is my second attempt.
ZWSold shows the first version before I started from scratch.

MultiChoice
As far as I got with my multiple choice idea (I think).
The code sucks, but the idea doesn't. Hopefully someone will take the information here and make an awesome script. (Eventers will love whoever does it)

Robot
The structure for a minigame where you can give commands to a robot and let it execute them.

SwitchSwapper
This is a tool which takes a project and attempts to swap pairs of switches and variables as specified in the config file. Its purpose is indeed to help make integration of event system simpler.
I think the idea is really cool and it would be awesome if someone extended it to work with  more things.


Btw. let's not forget my mouse implementation into the default scripts:
http://www.mediafire.com/?jiztozljehj

Multi-threading in RGSS

posted Feb 28, 2010, 5:44 AM by Zeriab NA

Here are a few thoughts on multi-threading in RGSS. They may very well be applicable to RGSS2, but on the other hand there might be differences.
I am assuming that you have knowledge on the multi-threading in general.

Single Core
It doesn't matter how many threads you make, only a single core on a single cpu can be utilized in RGSS.
I believe this is a short-coming of the Ruby interpreter itself although I am not completely sure.
It does seem like the Audio runs in a thread outside the Ruby environment and thus may be able to use another core to process the audio. (I am not completely sure about this)
In conclusion you should not expect any speed improvements by using more threads.

Graphic.update
As you can derive from the name this method updates the graphics. It also tries to keep the frame-rate stable. This means that it halts until enough time has passed.
The problem is that Graphic.update does not only halt the thread calling the  method. It halts all threads. You cannot stop calling Graphics.update since you will get a Script Hanging error after 8-10 seconds.
You can basically expect the performance of the other threads to decrease significantly.

Sprites
Sprites appear not to be thread-safe. If you create sprites in one thread while another thread calls Graphics.update you may very well face a race condition which causes the game to crash.
It may perfectly be possible to safe-guard the Graphics.update call (by aliasing and making critical regions)  so that the internal Graphics.update will never be called.
I suggest that you try to have all the sprite creation in the same thread as the Graphics.update. That way I don't think any nasty surprises will await you and allow normal thread-safety measures.

Conclusion
Performance-wise there is no real benefit in using more than 1 thread. In fact it will probably decrease the performance. Therefore only use more than one thread if alternatives makes the scripting much more complicated.
An example of where multi-threading could help is with a loading script or progress script where one thread takes care of handling sprites and updating Graphics.update as little as possible while the other thread does its loading or fancy (slow) algorithms.

__END__

posted Feb 18, 2010, 11:45 AM by Zeriab NA

Here's a little mention about an interesting special term, __END__.
The rest of the section after that will not be run. In fact I believe the parser will stop at __END__ and therefore won't even build the abstract syntax tree for what comes afterwards. (An effect is the lack of syntax checking)
This can be used for preventing the inclusion of test code except when you want to use it.

class Medal
  include Comparable
  attr_reader :titel, :time
  def initialize(titel, time)
    unless time.is_a?(Numeric)
      raise ArgumentError.new("Time must be a numeric")
    end
    @titel = titel
    @time = time
  end
 
  def <=>(medal)
    return time <=> medal.time
  end
end
 
__END__
 
class TestError < StandardError; end
 
bronze = Medal.new('Bronze', 180)
bronze2 = Medal.new('Bronze', 180)
bronze3 = Medal.new('Bronze3', 180)
silver = Medal.new('Silver', 105)
gold = Medal.new('Gold', 87.5)
 
unless (bronze == bronze2)
  raise TestError.new("Medal.== does not compare #{bronze.inspect} " +
                      "and #{bronze2.inspect} properly")
end
 
unless (bronze == bronze3)
  raise TestError.new("Medal.== does not ignore the title")
end
 
unless (silver <=> bronze) == -1
  raise TestError.new("Medal.<=> does not return -1 when its time is less" +
                      " than the medal compared to")
end
 
unless (silver <=> gold) == 1
  raise TestError.new("Medal.<=> does not return 1 when its time is greater" +
                      " than the medal compared to")
end
 
unless (bronze <=> gold) == 1
  raise TestError.new("Medal.<=> does not preserve transitivity.\n" +
                      "I.e. <=> is highly problematic.")
end
                   
p 'Medal testing completed successfully'


I am sure you can see how it can be helpful in providing test data for scripters while being ignored normally.
Of course you could use a if false ... end for similar effect.
The different is that the abstract syntax tree will be created while it will not when using __END__. On the other hand copy-pasting several sections into a single section may disable sections.

Waiting for movement

posted Jan 7, 2010, 5:39 AM by Zeriab NA

To show one use of Interpreter command_355 (RMXP) I'll show how you can make events wait for movement of a single event or the player to finish rather than all movements which the Wait For Movement's Completion command does.
Let's add this little snippet for checking whether Game_Character is moving or not. (Both Game_Player and Game_Event inherits from that class: (Add anywhere above main)
  1. class Game_Character
  2.   ##
  3.   # Returns :wait while the character is moving and
  4.   # returns nil otherwise
  5.   #
  6.   def wait_for_movement
  7.     if @move_route_forcing
  8.       return :wait
  9.     end
  10.   end
  11. end
It returns :wait when called. You can now put $game_player.wait_for_movement in a script call and that event will wait until the player has stopped moving before continuing.
Likewise you can use $game_map.events[7].wait_for_movement for waiting until the event with id 7 has finished its movement.
It's simple, elegant and much easier than had the wait functionality been removed from command_355. It was an excellent idea in the default scripts albeit a little poorly executed and unfortunately not well-understood.

Next I will add some syntactic sugar to use in the call scripts which makes waiting for specific events easier. It's not needed at all, but it is more user friendly and nicer to use.
Add this script anywhere above main:
  1. class Interpreter
  2.   ##
  3.   # Wait for movement where: (Nothing will happen in combat)
  4.   # id < 0: Current event (if there is one)
  5.   # id = 0: Player
  6.   # id > 0: Event with that id (if there is one)
  7.   #
  8.   def wait_for_movement(id = -1)
  9.     # If in battle
  10.     return if $game_temp.in_battle
  11.     # Get actor
  12.     actor = nil
  13.     if id < 0 && @event_id > 0
  14.       actor = $game_map.events[@event_id]
  15.     elsif id == 0
  16.       actor = $game_player
  17.     else
  18.       actor = $game_map.events[id]
  19.     end
  20.     # Wait for actor's movement
  21.     unless actor.nil?
  22.       actor.wait_for_movement
  23.     end
  24.   end
  25.   ##
  26.   # Wait for player's movement
  27.   #
  28.   def wait_for_players_movement
  29.     wait_for_movement(0)
  30.   end
  31. end
You can now simply put wait_for_movement in a script call and it will wait for its own movement to to be completed. (Note that it will simply skip if the interpreter does not originate from a map event. See my Common Events tutorial for more information on this subject)
You can specify a specific with wait_for_movement(id) where id is the id of the map event. If you for example want to wait for event 7 then use wait_for_movement(7).
You can wait for the player by using wait_for_movement(0) or by using wait_for_players_movement.

Note that it will do nothing if called in battle.

Commenting =o

posted Jan 7, 2010, 5:39 AM by Zeriab NA

You cannot comment on the entries I post here, so I have decided to post RGSS related entries also in my blog here at owainc.net.
I will add links for the entries to there respective entries in that blog as a comment. This means you will actually have to on the entry or the 1 comment at the bottom to see the link. This is just to avoid clutter.

Note that you may have to register to see the blog.

*hugs*

1-10 of 22

Comments