Slip into Ruby: An introductory guide to RGSS for beginners.

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
2,603
Reaction score
1,941
First Language
English
Primarily Uses
RMMV
Attention, Duelists!


I've been writing a series on getting started with RGSS (aimed primarily at RPG Maker VX Ace) since 2012, and there are now several parts available. I started it on rpgmaker.net, but thought I would also share it with the fine folks here!


Chapter 1: Making a bestiary

-- Part 1: http://rpgmaker.net/articles/694/
-- Part 2: http://rpgmaker.net/articles/835/
-- Part 3: http://rpgmaker.net/articles/1096/
-- Part 4: http://rpgmaker.net/articles/1108/

Chapter 2: Under the Hood (Breaking down the default scripts)

-- Part 1: The modules

---- Section 1: http://rpgmaker.net/articles/1109/ (covers Vocab, Sound, Cache and DataManager)
---- Section 2: http://rpgmaker.net/articles/1110/ (covers SceneManager and BattleManager)

-- Part 2: Game Objects

---- Section 1: http://rpgmaker.net/articles/1114/ (covers Game_Temp, Game_System and Game_Timer)
---- Section 2: http://rpgmaker.net/articles/1116/ (covers Game_Message, Game_Switches, Game_Variables, Game_SelfSwitches, Game_Screen and Game_Pictures)
---- Section 3: http://rpgmaker.net/articles/1120/ (covers Game_BaseItem, Game_Action and Game_ActionResult)
---- Section 4: http://rpgmaker.net/articles/1121/ (covers Game_BattlerBase and Game_Battler)
---- Section 5: http://rpgmaker.net/articles/1129/ (covers Game_Actor)
---- Section 6: http://rpgmaker.net/articles/1130/ (covers Game_Enemy, Game_Actors, Game_Unit, Game_Party and Game_Troop)
---- Section 7: http://rpgmaker.net/articles/1137/ (covers Game_Map)
---- Section 8: http://rpgmaker.net/articles/1229/ (covers Game_CommonEvent, Game_CharacterBase, Game_Character, Game_Player, Game_Follower, Game_Followers, Game_Vehicle and Game_Event)
---- Section 9: https://www.rpgmaker.net/articles/1351/ (covers Game_Interpreter)

-- Part 3: Sprites

---- Section 1: https://rpgmaker.net/articles/1353/ (covers Sprite_Base and Sprite_Character)
---- Section 2: https://rpgmaker.net/articles/1355/ (covers Sprite_Battler, Sprite_Picture and Sprite_Timer)

-- Part 4: Spritesets

---- Section 1: https://rpgmaker.net/articles/1356/ (covers Spriteset_Weather, Spriteset_Map and Spriteset_Battle)

-- Part 5: Windows

---- Section 1: https://rpgmaker.net/articles/1363/ (covers Window_Base)
---- Section 2: https://rpgmaker.net/articles/1369/ (covers Window_Selectable, Window_Command and Window_HorzCommand)
---- Section 3: https://rpgmaker.net/articles/1376/ (covers Window_Help, Window_Gold, Window_MenuCommand, Window_MenuStatus, Window_MenuActor, Window_ItemCategory, Window_ItemList, Window_SkillCommand, Window_SkillStatus and Window_SkillList)
---- Section 4: https://rpgmaker.net/articles/1383/ (covers Window_EquipStatus, Window_Status, Window_SaveFile, Window_ShopCommand, Window_ShopBuy, Window_ShopSell, Window_ShopNumber and Window_ShopStatus)
---- Section 5: https://rpgmaker.net/articles/1392/ (covers Window_NameEdit, Window_NameInput, Window_ChoiceList and Window_NumberInput)
---- Section 6: https://rpgmaker.net/articles/2686/ (covers Window_KeyItem, Window_Message and Window_ScrollText)
---- Section 7: https://rpgmaker.net/articles/2693/ (covers Window_MapName, Window_BattleLog, Window_PartyCommand, Window_ActorCommand, Window_BattleStatus, Window_BattleActor, Window_BattleEnemy, Window_BattleSkill, Window_BattleItem, Window_TitleCommand, Window_DebugLeft and Window_DebugRight)

Those are the ones that are available so far. I'll update the topic as I write more (currently putting one up every Tuesday whenever I'm not totally swamped with other stuff). As with the guys on RMN, I welcome comments, criticisms and suggestions from you guys too. Hopefully someone will get some use out of this!
 
Last edited:

Warpmind

Twisted Genius
Veteran
Joined
Mar 13, 2012
Messages
933
Reaction score
574
First Language
Norwegian
Primarily Uses
Oh, hey, bookmark'd! :D
 

Mako

Veteran
Veteran
Joined
Mar 13, 2012
Messages
276
Reaction score
47
First Language
English
Primarily Uses

Kes

Veteran
Veteran
Joined
Aug 3, 2012
Messages
22,281
Reaction score
11,686
First Language
English
Primarily Uses
RMVXA
I've just been reading your first article, and it looks like it's written for people like me who, despite good will and some effort, haven't a clue.  Now, for instance, I discover that a method is a subroutine or function and suddenly, a whole load of things people have said at me start to make sense.

I am not, generally speaking, a cat lover, but I think yours is going to be dear to my heart.

thank you for this.
 

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
2,603
Reaction score
1,941
First Language
English
Primarily Uses
RMMV
Thanks for the encouraging responses guys! It's posts like that which make the whole thing worth doing for me, so I'm glad people are finding it useful. If there's ever anything I cover that you're not 100% sure about, please ask and I'll do my best to clarify it!
 

_Shadow_

Tech Magician Level:
Moderator
Joined
Mar 2, 2014
Messages
4,068
Reaction score
2,653
First Language
Greek
Primarily Uses
RMMZ
Really? What exactly I wanted to do a revision on what I already learned and I suppose a good start to learn new things.

Thank you very much indeed, I will check them and give you feedback ASAP!
 

Tokumei No

Kojima Fan
Veteran
Joined
Jul 4, 2014
Messages
199
Reaction score
39
First Language
Italian
Primarily Uses
That's interesting! Your precious guide will be enormously helpful to me when I'll be able to buy the complete edition of VX Ace.

Thank you :D
 

Kes

Veteran
Veteran
Joined
Aug 3, 2012
Messages
22,281
Reaction score
11,686
First Language
English
Primarily Uses
RMVXA
I have a question about the material covered in Chapter 1, Part 1.

When you are putting the various methods together under initialize (and, by the way, I am assuming that def means define.  Does it?), this is what you have:

class Animal def initialize @age = 0 end def breathe #code for breathing end def age @age end def age=(val) @age = val endendWhy do you start with age, go to breathe and then go back to age again?  Instinctively I would have put all my age stuff together, and then done breathe.  The root question is - is the order in which things are done in initialize important or not?

Thanks.

EDIT

Another question. 

In the final section, you have:

def age = (val) @age = val endWhy is val in brackets the first time and not in brackets the second time. i.e. what is the function of those brackets?
 
Last edited by a moderator:

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
2,603
Reaction score
1,941
First Language
English
Primarily Uses
RMMV
It honestly doesn't matter what order you write methods in. Even methods which call methods that are defined (yes, that's what def means) after them will work as intended. There's no particular reason I didn't define the age getting method before breathe, and you could certainly have done it that way if order was important to you.

The reason val is in brackets the first time is that it's a parameter and parameters for methods always go in brackets. The method is actually called "age =" and the equals sign is part of the method name. The second time val is referenced, it's setting the instance variable @age to the supplied value from the parameter, and assignments don't need brackets unless you need to specify operations that happen first.
 
  • Like
Reactions: Kes

Kes

Veteran
Veteran
Joined
Aug 3, 2012
Messages
22,281
Reaction score
11,686
First Language
English
Primarily Uses
RMVXA
Thank you for the quick reply.  I think I understand now.
 

_Shadow_

Tech Magician Level:
Moderator
Joined
Mar 2, 2014
Messages
4,068
Reaction score
2,653
First Language
Greek
Primarily Uses
RMMZ
def age=(val)
        @age = val
    end

Do you actually override the  = operator that way, by telling Ruby how to treat = when it comes to encounter one for age?

Or am I wrong?

Can you actually make methods that contain = character?
 
Last edited by a moderator:

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
2,603
Reaction score
1,941
First Language
English
Primarily Uses
RMMV
The equals sign is actually part of the name of the method; it simply lets you use the method as if it were performing an assignment, so for instance:

tiddles = Animal.new

tiddles.age = 2

We are calling a method called "age =" on tiddles, supplying 2 as the parameter.
 

_Shadow_

Tech Magician Level:
Moderator
Joined
Mar 2, 2014
Messages
4,068
Reaction score
2,653
First Language
Greek
Primarily Uses
RMMZ
tiddles = Animal.new

tiddles.age = 2

So tiddles is an object, and specifically an instantiation of the class Animal.

So the age on the tiddles instance takes as new value 2.

I think I get it.

You create a method so you can access the @age class variable right? It has to do with the variable scope is that it?

So you can assign a new value to @age from anywhere by using that method. Am I right?
 

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
2,603
Reaction score
1,941
First Language
English
Primarily Uses
RMMV
Yeah, the whole point of encapsulation is that because @age is an instance variable I can't just do tiddles.age = 2 without having a method that specifically allows me to do so. That's why there's a method which sets it, so that I can set it outwith the class.

Honestly, this isn't actually vastly important when your setter method is doing nothing but setting the variable's value, but imagine we had some sort of sanity checking in place:

def age=(val)

  @age = [[val, 100].min, 0].max

end

Now if I do something like tiddles.age=125 it'll max it out at 100; if I do tiddles.age = -20 it'll set it to 0. If it's an attr_accessor and you don't have a setter method, these kinds of checks are harder to police because anything could just do tiddles.age = whatever and when you were debugging to find out why Tiddles was suddenly -20 years old you'd have to look for every part of the code where Tiddles had his age changed. Make sense?
 

_Shadow_

Tech Magician Level:
Moderator
Joined
Mar 2, 2014
Messages
4,068
Reaction score
2,653
First Language
Greek
Primarily Uses
RMMZ
Yeah, the whole point of encapsulation is that because @age is an instance variable I can't just do tiddles.age = 2 without having a method that specifically allows me to do so. That's why there's a method which sets it, so that I can set it outwith the class.

Honestly, this isn't actually vastly important when your setter method is doing nothing but setting the variable's value, but imagine we had some sort of sanity checking in place:

def age=(val)

  @age = [[val, 100].min, 0].max

end

Now if I do something like tiddles.age=125 it'll max it out at 100; if I do tiddles.age = -20 it'll set it to 0. If it's an attr_accessor and you don't have a setter method, these kinds of checks are harder to police because anything could just do tiddles.age = whatever and when you were debugging to find out why Tiddles was suddenly -20 years old you'd have to look for every part of the code where Tiddles had his age changed. Make sense?
Yeah since I know Java but not much on Ruby, I couldn't link that properly. Now I know what exactly is going on! :D :)   :thumbsup-right:

Thanks for guidiing me on that mate.

Yes it makes sense. I take what you say in the end, is setting max and min values for the argument, so in case there will be an invalid input, there will not be a filter needed and the method will not throw an exception neither it will return anything stupid that will create hard-to-trace issues on debug. You set a max value and a min value. Then it is an auto limiter. Cool.

I just have one case. I don't understand the syntax of the code. 

 @age = [[val, 100].min, 0].max

This is really strange syntax,  how does it go?

I mean val is an argument all right, then isn't it more rational to be like  @age = [val, 100, 0] or something? Like @age = [argument [maxvalueallowed, minvalueallowed]] as three arguments or something. What I wrote might make no sense at all.

Remember I still try to figure out Ruby :)
 
Last edited by a moderator:

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
2,603
Reaction score
1,941
First Language
English
Primarily Uses
RMMV
Okay, the inner clause is evaluated first, so it checks to see what the minimum value between val and 100 is. If val is less than 100, that'll be val, otherwise it'll be 100. This prevents any val greater than 100 being considered.

After it's determined the minimum value from those two, we wanted it to figure out the maximum value between that and 0. (if we'd supplied -20 for val, it would have been chosen for the first clause). This prevents values less than 0.

The way you were saying it would be more rational would be setting an array, which isn't what I was doing. I was first making sure the value supplied wasn't too high, and then making sure it wasn't too low. The equivalent would be something like:

if val > 100

  @age = 100

elsif val < 0

  @age = 0

else

  @age = val

end
 
Last edited by a moderator:

_Shadow_

Tech Magician Level:
Moderator
Joined
Mar 2, 2014
Messages
4,068
Reaction score
2,653
First Language
Greek
Primarily Uses
RMMZ
 @age = [[val, 100].min, 0].max

Oh! so method min takes [val, 100] as input arguments, gets executed, then returns something.

Then we got [something,0].max the same way.

min means you minimize to 100 whatever is above 100, or else if it is below give it its given value.

max means if something is below 0 maximize it to 0.

But shouldn't the logic be like

 @age = [[val, 100].max, 0].min

instead of

 @age = [[val, 100].min, 0].max?

Like 100 is the max value and then 0 is the minimum? Why would it work with an  opposite logic?   :unsure:  

I hope I make sense here.
 

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
2,603
Reaction score
1,941
First Language
English
Primarily Uses
RMMV
No, because then if we run through test cases where you supply 120 or -20 as the arguments:

[val, 100].max will check what the maximum value is between 100 and 120, and choose 120.

Then [120, 0].min will check the minimum value between 120 and 0, and choose 0. So by entering a higher-than-max value, your algorithm is setting it to 0 instead of 100.

Conversely:

[val, 100].max will check what the max value is between -20 and 100, and choose 100.

Then [100,0].min will check the minimum value between 100 and 0, and choose 0.

Basically, if you did it the way you've described you'll always end up with 0.

In other news, the next part of Slip into Ruby is up! This one delves into Game_BattlerBase and Game_Battler! (warning: it's looooooooooooooooooong)

http://rpgmaker.net/articles/1121/
 

Kes

Veteran
Veteran
Joined
Aug 3, 2012
Messages
22,281
Reaction score
11,686
First Language
English
Primarily Uses
RMVXA
I have two questions concerning Chapter One, Part 2

I have worked through this part as far as where I should be able to interact with the NPC and get a simple list of enemies.  However, when I go to playtest this, the following error message comes up:

line 7

class/module name must be CONSTANT

class window_EnemyList < Window_Selectable

I assume that this is telling me that the name I have given to the class under super is not the same name as I have defined below it.  However, I have compared the two instances of the name very carefully, and cannot see any difference.  Can you please tell me what my mistake is?  Here is the full coding so far.

class Scene_Bestiary < Scene_MenuBase def start super @list_window = window_EnemyList.new(0, 0, 200) endendclass window_EnemyList < Window_Selectable def initialize(x, y, width) super(x, y, width, Graphics.height - y) data = [] self-index = 0 activate refresh endenddef refresh make_item_list create_contents draw_all_itemsenddef make_item_list @data = $data_enemies.compactenddef item_max @data ? @data.size : 1enddef draw_item(index) item = @data(index) if item rect = item_rect_for_text(index) draw_text(rect, item.name) endendMy second question is this.  You have referred several times to an array.  What is an array?

Thanks.
 

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
2,603
Reaction score
1,941
First Language
English
Primarily Uses
RMMV
The error is because you've written "window_EnemyList" and it needs to be "Window_EnemyList"; class names are case-sensitive.

Sorry, I thought I'd explained at some point in the series what an array was!

Okay, so a variable holds a single value. I could have a variable called "index" with value 23, or a variable called "text" with value "this is some text". I assume you're at the least familiar with that concept.

An array is like a collection of variables stored in a variable. So I could have an array called "indexes" and the value will be [23, 5]; to refer to these we say the name of the array and the index from the array we wish to access: indexes[0] would be 23, and indexes[1] would be 5, as array indexes start at 0.
 

Users Who Are Viewing This Thread (Users: 0, Guests: 2)

Latest Threads

Latest Posts

Latest Profile Posts

Trying to get enough of an outline for my game to know what art needs to be made. I'm very out of practice with writing, having focused on art, and I'm realizing that I really missed it.
Make a Game in RPG Maker MZ: Episode 4 is now LIVE! Join us as we create our random encounter system. Random doesn't mean the player can't have some control! Want to figure out how, then tune in!
I must now resume my “things that make me money” activities, and relegate game-mak to a day or two a week. Maybe a lil in the afternoon, but I usually work on “career” level stuff then too.
Sotheby's had send me a mail this moment, stating an auction base for a book of mine at 150.000 euro. I found that book in a trashbin. It look like those chests that simply hide the final sword in an RPG.
I need to find some mapping tutorials cause I'm soooo terrible at it. like just awful lol. I've been having a huge asset issue with anything that isn't battle related unfortunately thanks to custom non-rtp characters.

Forum statistics

Threads
103,457
Messages
999,438
Members
134,990
Latest member
Popcorn_Kitty_Gamer
Top