Writing SDK Style Scripts?

Started by Heretic86, September 24, 2014, 09:19:01 pm

Previous topic - Next topic

Heretic86

One of the problems that I run into a lot with RMXP is that some of the methods that I want to make changes to are not easily modified without consequences.  Specifically, 'Passable?' for both the Map and Character.  The problem is that if I rewrite the entire method, I know it can severely decrease compatability with other scripts.  The alternative would be to run through the iterations made in Passable which can sigificantly decrease performance.

Normally, I dont like the RMXP SDK (any version of it) due to compatability issues, so I try to avoid dependancy on it as much as possible.  But I now have a situation where I need to directly alter the way Passable works, and have to create an SDK Style script in order to maintain both compatability and performance.  The current community SDK, even up to version 2.4 does not offer an alternative to Passable (Map or Character), and I do need to write my own.  I have a lot of reasons for needing to do this.

My question about an SDK Style script is rather generalized. 

What are some good practices for writing an SDK Style Script?

There are a number of local variables calculated in the method.  Should all of these local variables be passed along to the sub-methods, or only ones that are relevant to that method?

My biggest concern is creating other issues with other scripts, and that is what I want to avoid.  Next, I want to offer as much functionality and performance as possible. 

Here are two examples:

Example 1

def passable?(x, y, d, event, self_event = nil)
# Determine Passability Bit from Direction
bit = (1 << (d / 2 - 1)) & 0x0f
# Some Comment
value = expensive_method(x, y, d, bit, event, self_event)
end


Example 2

def passable?(x, y, d, event, self_event = nil)
# Determine Passability Bit from Direction
bit = (1 << (d / 2 - 1)) & 0x0f
# Some Comment
value = expensive_method(bit)
end


The difference between the two is the arguments passed to expensive_method.  Only one argument is needed for normal operations to get back the expected results.  However, for other scripts, more arguments may be needed that are either passed as arguments to the main method (like event, new_x, new_y, etc) in order for modified results to be returned by Aliases from other scripts.  In order to maintain performace, is it better to prevent recalculations by passing along more arguments?  Some arguments, once excluded, as far as I know, cant be retreived, such as a local variable inside of an iteration.  Should that local variable be passed along in an argument to methods that are called within the expensive iterations even if they are not needed by that method?

I am aware I can put *args in the Arguments list for each method.  Is that a better way to do this?  This topic is highly debatable and will vary from Scripter to Scripter.  So I just wanted to get a general idea of how people would like an SDK Style script to be written.

Suggestions?
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

KK20

Whether you rewrite the method or go for an SDK alternative, you're still going to have compatibility issues. I also don't think rewriting or aliasing 'passable?' is a common thing either, namely only holding true for pixel-based movement scripts--which also continues with the whole "compatibility issues" since each scripter probably has their own, unique 'passable?' methods.

QuoteShould all of these local variables be passed along to the sub-methods, or only ones that are relevant to that method?

Only those that are relevant. Generally, you lose performance the more variables you pass and the more methods you call within that method.

Use *args if you do not know how many parameters the method might have. It's better than getting 'invalid number of arguments'.

I say just do what you have to do; if it's not compatible 'out-of-the-box', then oh well. Some scripts just aren't meant to thrown into any game like a fitting puzzle piece.


Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Ryex

September 25, 2014, 11:59:59 pm #2 Last Edit: September 26, 2014, 12:03:12 am by Ryex
Frankly the SDK was the worst conceived best intentioned notion to ever come out of the RMXP community. it perpetuated this myth that All scripts COULD be compatible. the truth is there is no such thing as perfect compatibility you can try real hard to modularize your system and raise the chances of compatibility but you can never guarantee it. the SDK just tricked people into thinking that you could.

There are some parts of RMXP that have absolutely no potential for compatibility between systems, passable? is one such place.

Stop worrying about compatibility. focus instead on good system design in all likelihood compatibility with most things will be a side effect.


tldr; How do you write SDK style scripts? you don't write SDK style scripts

(by that I mean that the original intention of the SDK was to promote compatibility so an "SDK style" would be a style that promoted compatibility, but the Real SDK did everything wrong in the attempt to create compatibility so dont use SDK style. just modularise and keep things simple.)
I no longer keep up with posts in the forum very well. If you have a question or comment, about my work, or in general I welcome PM's. if you make a post in one of my threads and I don't reply with in a day or two feel free to PM me and point it out to me.<br /><br />DropBox, the best free file syncing service there is.<br />

Heretic86

So what happened specifically that the SDK went so horribly wrong?  Was it not modularized enough?  Too modularized?  Learning why things go wrong is often a very good step to learning how to make things work correctly.

As far as passable? goes, is something like this more akin to proper modularization?

def passable?(x, y, d, self_event = nil)
return false unless valid?(x, y)
bit = (1 << (d / 2 - 1)) & 0x0f
for event in events.values
  if event_conditions?(x, y, d)
    if not event_passable?(*args)
      return false
    end
  end
end
return true


Thats not real code, but would that basically be how it would be more modularized?
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

KK20

The fact that you HAVE to use it and adjust to its standards is already bad enough, especially when people already wrote scripts that just extend and/or assume you are using the default scripts.
If Enterbrain were to make an update that changes the default scripts to be like SDK, it effectively destroys existing scripts (and no one is going to devote their life to fixing them all either).

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Heretic86

So basically, two sets of standards.  Gotcha.  If that is the case, I'm gonna modularize passable and just do what I want it to do.  If its that rarely changed, it shouldnt be a big deal.  It should have been a bit more 'modularized' to begin with.  Then again, for pixel movement scripts, it would have just just been overwritten also, and that is not my intent.
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

Heretic86

PLEASE LIST SCRIPTS THAT REPLACE GAME_MAP PASSABLE OR GAME_CHARACTER PASSABLE

Im still working hard on this. 

Currently, I think I have something that works exceptionally well.  The good thing is this script I am working on is not that big, just highly modularized.  Im in the process of writing a bunch of personal "holy grail" scripts that would all normally require one of the Passable definitions to be fully replaced, and they are all working together perfectly.  My "holy grail" is that they normally would not work together at all, and this modularized script lets them all work together so I think I've done a good job so far.  The scripts include Stairs (due to allowing for Evented Stairs via Terrain Tags), Downhill Ice (also Event Terrain Tags), NPCs on Event Tiles, Control Bush Passage, TOTAL Control over Movement (labeled RTP) which has also opened up an option for Boat Vehicles and Oversized Vehicles (and yes Boats can move on Water), and they ALL work together.  Also planned is a Moving Platform Script, but havent started that yet.

I know this modular script wont be 100% compatible.  Its not supposed to be.  What I want to do right now is to take a look at any other scripts that replace Passable, just so I can see the code.  I don't intend on rewriting those scripts.  I just want to see what is different and what their respective authors needed to change so if there is anything I'd need to adjust in my code that I havent currently thought of, I can at least allow for it.  This goes for ANY script you know of that REPLACES the PASSABLE methods.  I'd suspect Pixel Movement and Screen Resolutions, but post those here anyway.  Its just to see if code CAN be written in such a way that it could be compatible.  That is all I care right now and why I want to see those scripts.

I might not reply, but post / link them so I can see them.  I'll edit this post in the future, but until then, just show me which scripts are altering Passable please.  Thanks guys.
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

Wecoc

Here are some:

Free Movement (Ace)
I have no idea how this works, and it's for Ace so maybe useless in that case.
http://forums.rpgmakerweb.com/index.php?/topic/7833-free-movement-off-the-grid-movement-script/

Semi-Though or 'Cockroach Event' (XP)
Special events (for example cockroaches) which are passable with events and player, but not the map.
http://www.mundo-maker.com/t6759-rmxp-semithrough-o-eventos-cucaracha

MOMOTARO - Passability Edits (XP) (The first script, not the second one!)
You can use passability by tile, events or terrain tag separately, and define on each actor which passability features has. Inspired on a Ace script by Yanfly.
http://www.mundo-maker.com/t10253-xp-sistema-momotaro

Half-step Movement (XP, incomplete!)
The tiles are 32x32 but the steps are 16px long. Inspired on the Wolf RPG Editor system.
http://www.mundo-maker.com/t9555-incompleto-movimiento-a-medio-paso

And maybe Mode7 & Neo-Mode7 will have changes too.

I also found this inside a game with a curious map system. It's a Game_Map passable? method edit:

  def passable?(x, y, d, self_event=nil, layers=[2, 1, 0], not_events=false)
    unless valid?(x, y)
      return false
    end
    bit = (1 << (d / 2 - 1)) & 0x0f
    unless not_events
      for event in events.values
        if event.tile_id >= 0 and event != self_event and
           event.x == x and event.y == y and not event.through
          if @passages[event.tile_id] & bit != 0
            return false
          elsif @passages[event.tile_id] & 0x0f == 0x0f
            return false
          elsif @priorities[event.tile_id] == 0
            return true
          end
        end
      end
    end
    for i in layers
      tile_id = data[x, y, i]
      if tile_id == nil
        return false
      elsif @passages[tile_id] & bit != 0
        return false
      elsif @passages[tile_id] & 0x0f == 0x0f
        return false
      elsif @priorities[tile_id] == 0
        return true
      end
    end
    return true
  end

Heretic86

Thanks!  Exactly what I needed!  Im glad you posted that because I saw something that I didnt allow for and adjusted it.  Its one of those big reasons Im holding off on release of this script.  I don't want to go the SDK way and have a hundred different versions with a hundred different bugs on initial release, and trust me, I've already changed at least a hundred things.  Its also part of the reason Im also building the supporting scripts prior to release also, as they've all caused me to rethink my logic to allow for a 100% compatibility rating right now as far as I can tell.  It also means the supporting scripts are ORDER FREE, so they should be able to be placed anywhere below the core script and don't need to be in any specific order.  There is one exception, but it is due to a dependancy. 

Man, these scripts are gonna knock your socks off!  Oh yeah, I can now make Characters "Float" without screwing with Map Positions, Collisions, or Z-Indexes at all!  Excluding the Free Movement script you've listed, I'd say all these scripts now exceed what these others can do AND 100% compatible.

Off Topic: I did learn one thing that I was doing wrong (already fixed).  I was making some adjustments to the Player class and was aliasing initialize in the Player class to add some new properties.  Bad no no that I never thought of before.  Since there is no initialize method in the Player class, making an alias causes incompatability issues.  It allows that script to work just fine, but any other scripts stop doing to player what they were intended to do.  Bad no no on my part that I've now learned from so Im now adding new Player properties from within the Character class initialize method instead of the Player class.  The rule I broke was not maintaining class structures.  Learn something new every day!  :p
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)