Yal... I have problem with add more monsters. I added 32 but in Monsterpedia (new name of my ...pedia) I have only 19 when I take this monster #macro monster_ORANGE_FOX 18 from start. When I take this monster for start #macro monster_FROG 22 i have 23. And when take this #macro monster_RABBIT 31 i have all 32. This 3 monsters these are the ones I choose at the beginning (NEW GAME).
Only shows me in MONSTERPEDIA these monsters before the one on the list + his.
EXAMPLE:
When I take #macro monster_HORSE 3 (number 3) I have in MONSTERPEDIA only 4 monsters:
#macro monster_HYENA 0
#macro monster_TIGER 1
#macro monster_GOAT 2
#macro monster_HORSE 3
Where is problem? :(
I make something like this:
On start Im take #macro monster_HYENA 0 (I have only HYENA in MOSTERPEDIA). I go fight. First monster with whom I fought it is #macro monster_BADGER 7. When I finish I have in MONSTERPEDIA 8 monsters (6 with "???" and HYENA and BADGER. Off course this "???" are a previous numbers of monsters before BADGER. And I go fight with another #macro monster_ELEPHANT 9. Now I have 10 monsters in MONSTERPEDIA. 7 with "???" (unknown) and 3 met by me.
These "???" these are the ones in front of the elephant. It should not immediately display a list of all that are added as unknown, ie with the characters "???"?Because he only adds when I get to know (the one I meet) and everything in front of him then (MACRO is about numbering), of course, those before the known (apart from those known) are marked with "???" that is, marked as unknown.
But it doesn't make sense. I think this is some kind of error or I am doing something wrong.
I changed your names to my monsters names. I checked everything 5 times. I missed nothing.
Nothing else I touched except the graphics.
And I check your demo. You have this same bug in it.
No plans, sorry. (The hardest part with making a collectible card game is making all the rules, and that's a very per-game-specific thing that's hard to make a general system for)
I'm just checking the update has the entire source code correct because I need to modify it, & you need to make some tutorials either a video with text or PDF so I can understand how to use it better thanks 👍
Hey Yal, I'm wondering if you could help me on what to do for making moves that can do the following:
-Metronome like effect, completely random move
-A random move from a specific type (Example: Channel, uses a random Ghost type move)
I'd also like to make one that deals a random status effect, a random move from a list of specific moves, and a random stat lower or raise, but those ones I could probably figure out on my own once I know how to make those two. Also, I guess the metronome like move would need a blacklist so you don't pull out a boss-only move or something.
The answer to all of them basically boils down to "make a list of all moves and then pick a random entry from the list"... for very narrow categories you could build these lists manually, but for large lists (e.g. Metronome specifically) you could do this automatically: loop over all moves (after you've defined them in init_moves) and add the move ID to the list if it's valid (you could check validity using a new "valid for metronome" property, or your own list of invalid moves)
Now for the tricky part, when to do the table lookup and how to work it into the move system... I think this would be the easiest way:
Make the move target the user (movetarg_USER), be of movecat_SUPPORT category, have no damage, but a 100% chance to trigger a special effect
The special effect is of a new movespfx_METRONOME type, the "detail" field could be a reference to which random list of moves to pull from
When the side effect is rolled (battlecontrol step event, line 778 onwards ("Side effects (user)"), you action_enqueue_prio the new move you pick from the list (thus making it be performed immediately instead of being scheduled based on the Speed stat). You can use battle_get_random_targets() to get a random valid target for the move, see the bcontrolstate_ACTIONSELECT_ENEMY section at line 393 onwards where it selects moves from the AI.
I'm actually trying to change how the battles works, but as a beginner I'm a bit lost on how the moves works.
Instead of the menu I would like to assign each attacks to one button, and the monster taking the damage if they were touched by an hitbox, but I don't really understand how to call for these moves. I guess it's about the amp_moves but I don't really know how.
Move IDs are stored in global.active_monster_party[amp_id,amp_MOVE1] through global.active_monster_party[amp_id,amp_MOVE4] and then move data is stored in the global.move_data array. So after you get a move ID from amp_MOVE1...amp_MOVE4 you can look up global.move_data using the ID you looked up and the move data constants (they begin with the prefix "mvd_")
Game Maker has support for networking, but I've never managed to get online multiplayer to work myself so I'm afraid I can't offer much help here.
Engine-wise I'm thinking you'd have the other player act like an AI player, and then their moves are based on what the player selects, with netcode synchronizing player inputs... you'll also need to make the RNG shared so things like variable damage and chance-based effects will be the same for both players.
2. how do I make items that make specific monsters learn a move like tms?
3. is there a way to make monsters give less exp when deafeated?
4. I tried making battles 2v2 but right now if the player only has one the game crashes, and I couldn't get the enemy to have 2 without crashing
5. is there a wat to make a certain encounter with a monster have the monster have set ivs?
6. right now I can't find a way to view the move descriptions
7. how would I exclude some monsters from the monsterepeda?
8. I found a bug: after you run from a monster if you press the main button a bunch it will take you to the spot where the player character is in the room
9. how would I make a monster that evolves into 1 of 2 monster randomly?
10. is STAB implemented? and if not how can I put it in?
1. There's a stat for this in init_monsters, search for "mond_EVBONUS_STAT".
2. This is a bit tricky, but the basic steps would be:
- Create a new itemtype + usescript (check out init_items for the context for what these means) and add the new items to init_items
- The usescript first checks if the monster is compatible (if you want to have a check like this) and then does something similar to mev_monster_learnmove_spawnmenu (check out obj_battlecontrol's step event at line 1022 to see how it handles whether the monster has empty move slots and can learn moves immediately).
3. EXP calculations are done in obj_battlemonster's step event, line 94. Currently it's based on the monster's levelup EXP but you could add a new stat to the monster data for this for instance, or just lower the factor from 0.1 to something lower.
4. What's the crash error message? Player monster slots should start as KO'd if there's not enough monsters left that can fight, and you need to generate enough enemy monsters to fill all their slots. Check player_step_fill line 33 for how horde battles are generated currently.
5. Check out obj_npc_trainer's User Event 0, line 11 onwards it generates monsters. You could do something similar with a new "set encounter" object which generates new monsters and then overrides anything you want to change. (I assume you want to use this for legendaries so it'd also set the battle mode to wild instead of trainer)
6. It's currently only used in the learn new move menu (mev_monster_learnmove_spawnmenu), I guess I forgot to put it in when making the pause menu...
7. The easiest way would be like this:
- Add a new constant before MONSTER_MAX named MONSTER_PEDIA_MAX which has a lower value
- Go to mev_pause_moncyclopedia and change the first loop to end at MONSTER_PEDIA_MAX-1 instead of MONSTER_MAX
- Give all excluded monsters an ID number between MONSTER_PEDIA_MAX and MONSTER_MAX
8. I don't understand your explanation.
9. I think something like this could work:
- Create a new evolution type "evotype_RANDOM"
- Every monster that has this evolution type has an ARRAY of evolution monsters (third slot in the evolution data)
- amp_earn_exp checks for levelup evolutions, after line 40 add a new case that checks for evotype_RANDOM, and if the level requirement is met, sets evo to: global.monster_evolution_mon[ monid][c][irandom(array_length(global.monster_evolution_mon[ monid][c])-1)]
10. Yes, it's computed in the script compute_damage, line 50.
How do I change the capture rate of each individual monster? and how to change how much exp each monster gives? also, how do I make battles have more monsters?
Check out itemuse_catch, which computes the catch rate for a given stone. Currently it's the same for all monsters, but you could add a new "catch rate" stat for each species (see init_monsters / init_monster), and then get the species data using the AMP_ID. (i.e., something like global.monster_data[global.active_monster_party[amp_id,amp_MONID],mond_CATCHRATE] )
Currently EXP is computed in obj_battlemonster's step event, case 30 (bmonsterstate_DIE), using the same formula as levelup EXP (script monster_get_next_level_exp), which in turn is based on the monster's EXP group. Easiest way to influence this is adding more EXP groups, but if you want full control you could add an "EXP loot" stat just like the catch rate, and use that. (You probably want something that scales with the level, but of course it depends on how you want your game to work)
Check out the variables global.player_side_monsters / global.enemy_side_monsters (set them to the number of monsters you want each side to have before you start the battle - currently this is done in the script player_step_fill)
Is there by chance already a system to exclude encountering monsters that are currently in your party? I seen the possibility of doing something within the ects_placeholder function, but with out doing a bunch of if statements?
There's no built-in system, but it should be easy enough to set up.
In obj_player's collision event with obj_encounterzoneselector, after line 8 insert some new code:
for(var b = 0; b < array_length(global.encounter_valid_monsters); b++){
for(var c = AMP_FIRST_ACTIVE; c < AMP_FIRST_ACTIVE + PARTYSIZE_ACTIVE; c++){
if(global.active_monster_party[c,amp_MONID] == global.encounter_valid_monsters[b]){
array_delete(global.encounter_valid_monsters,b,1)
b-- //Deleting shifted everything back one step so re-check
break;
}
}
}
(this is completely untested so use with care)
the encounter_valid_monsters array is common to all ects_* (EnCounter Table Setup) scripts so modifying it directly like this means it should work everywhere in the game.
Thank you. So far after testing it's worked perfectly. One more thing. What would best way to go about have a "Release Monster" from party in status menu? Thanks again for the help.
Call amp_clear_monster() on its AMP ID to reset a monster's data (AMP = Active Monster Party is the list of "currently loaded" monsters, e.g. party, boxes and enemies).
Sorry to bother you again, but still learning. I'm struggling on updating the monster part list. Maybe you can point me in the right direction on what I'm missing. This is what I have:
It looks pretty reasonable, but you both update and delete daddy.daddy... I think you meant this? (destroying the "are you sure?" menu and the "what do you want to do?" menu)
instance_destroy()
instance_destroy(daddy)
(also of course you need to set my_monster to the AMP_ID (index in the Active Monster Party array) of the monster you want to delete when you create the menu that eventually runs mev_pause_monsters_release_confirm() , so the variable has a valid value... I presume you're doing this?)
Easiest way would probably be to add a new argument to init_monster which is supposed to contain an array with at least four elements; trigger constant, trigger function, name string, and description string (the last two are optional but you probably want them for the status screen later), and then go through init_monsters and make sure every monster gets an ability. (Of course you need to define new "mond_" constants for these new data points and increase MONSTER_DATA_MAX accordingly, on top of adding the trigger constants and making some scripts)
The idea is that you add triggers wherever an ability could affect something: every turn, on damage, when first entering battle, etc. Check if the monster in question has the matching trigger constant, and if so, run its script. For your Water Absorb (and Flash Fire, Lightningrod, etc) example specifically, check out obj_damageapply's Alarm 0 event, near the bottom:
You'd basically want a check like this, but for the monster's ability instead of its item. (And since it might potentially cancel out damage, you want it at the TOP of the event instead - the "water absorb" ability effect script would set my_dmg to a negative value before it's applied, so it becomes healing)
Side note: if you want monsters to potentially have different abilities, you should also add ability slots to the "amp_" (Active Monster Party) system, and make amp_generate_monster pick a random ability out of the available choices from the species data (and of course, you look up AMP data instead of MOND data when you check if the ability applies). If you're gonna reuse abilities a lot you'd probably want to make a whole ability data array and have references to that instead of storing the entire trigger+script+name+description per-monster. But one step at a time!
Maybe a bit of a weirdly specific question, but I was thinking of pokemon like Spinda, where their markings are essentially randomly placed. Usually I would do this with a clipping mask and a random x and y coordinate when drawing the sprite, but I was curious if you knew off the top of your head if this would work? I would probably need to add the X and Y variable to the individual monster, and use that?
I think the easiest way to do things like this would be to expand global.monster_data and add a "draw script" field. Whenever the monster is drawn, invoke this script instead of just draw_sprite/draw_sprite_ext (you can find all cases where a monster is drawn by doing a project-wide search for the "mond_SPRITE_BATTLE" constant). For monsters that don't need any special drawing, you'd add a default script that just draws the sprite like normal.
This is gonna be a bit tricky since a lot of the drawing is in menus (shrine terminals, status screen etc) so you'd probably need to add a new type of GGUI element that contains both a sprite and a script to draw it with (right now monsters are drawn in menus by creating a sprite element containing their sprite).
For the random markings themselves, the easiest way would be to use random_set_seed() and construct the seed from something that's unique to the monster and won't change - e.g. some sort of hash of their IVs (or you could give them a new "ID number" field set to like, irandom(9999999) when generated with amp_generate_monster() if you think that's easier), then generate the random coordinates to draw with, and finally randomize() to reset the RNG again. This way, the random numbers will always be the same for the monster, but you don't need to store them in any way.
Thanks so much for all your super in depth answers, it's always helpful!
Curious because I couldn't see any built in function for it, what would be the easiest way to change text speed temporarily? To give the effect of someone speaking slowly, for instance.
Secondly, I don't see an easy way to do this in your code anywhere, so I was curious about "gift" monsters. I.E. an event that just straight-up gives one specific monster upon talking to someone.
Gift monster ID's easier, so let's start with that.
Try amp_get_new_party_id to get the ID of the first empty slot in the party. If NONE, there's no empty slot - either abandon the gift procedure and tell the player they need to make some room in the party, or amp_get_new_box_id to get the first empty slot in the storage system instead. When you've got an empty slot, use amp_generate_monster to actually create a monster. (And optionally, give it a held item, special moves and so on - check out all the fun stuff in Scripts --> Data Mangling --> Active Monster Party). Also call msh_recompute_seencaught, in case the player didn't have this monster dex-ed yet.
(You can see an example of this stuff in action if you check mev_intro_starterselect_confirm.)
Now for text speed: There's two places where text speed is used, both in the message_handle script.
Line 17:
for(var c = 0; c < 2 + 2*k_a; c++){ //(main speed control - this many letters are typed per game step)
and line 23:
message_cooldown += 10; //(temporary pause on detecting the "|" character)
Depending on what needs you have, you could change either of those to put in some more speed control. I.e. instead of typing 2 + 2*k_a letters per step, you could type global.text_speed*(1 + k_a) letters, where the text speed variable defaults to 2 but there's a new "cc_textspeed" cutscene command script (see Scripts --> Cutscene System --> Cutscene Commands) which lets you change it at will. (I.e. change it to 1 to type more slowly, or change it to 99999 to reveal text instantly (but | characters can still be used to add dramatic breaks))
And of course, if you just want to add dramatic breaks or show someone enunciating a word extra clearly, there's no need for extra code - you could just sprinkle in some |s - one between each letter |l|i|k|e| |t|h|i|s, or a bunch at once when someone's...||| catching their breath.
There's no breeding mechanic built in. It probably wouldn't be TOO hard to add one, but still pretty involved:
Set up "egg groups" and assign monster species to them. Not sure what's the best way here, but since you won't check them very often you don't need to worry about performance.
Add a daycare (or somesuch) where you can deposit monsters. Easiest way would be to functionally add a new storage box, which can't be accessed from the shrine PCs. Every time the player takes a step, you could loop over every monster in this box and give them EXP (if you wanna copy Pokémon wholesale), but you'd also tick up some daycare counters every time you reach a step threshold (256 or something)
When monsters of a matching egg group are in the daycare, each Egg Tick you'd roll a random number to see if it's time to create an egg.
I think the easiest way would be to have an "egg flag" in the AMP data, which is true for eggs and false for other monsters. If the egg flag is true, the monster is considered fainted (so it can't be sent out) and checking its status will give you a special screen with the hatching info. The moment you generate an egg in the daycare, you actually generate the lowest evolution of the mother (and put it in another slot in the Daycare Box - or if you want to be able to generate more than one egg at a time, you might want to have a special Egg Box instead), and then just sets its egg flag to true. (You could also manually overwrite data for things like inheriting IVs, Egg Moves and so on)
If the player has any eggs in the party, you'd reduce the hatch counter for every egg in the party every Egg Tick, and if an egg hits zero, abort the loop and go to a hatching sequence (which you'd handle similar to how the monster evolution works now: set the load position, change rooms, go back to the room you were in when it ends).
Yeah, just include the value of global.player_name in the message.
Easiest way would probably be to make a new type of signpost (a child of the obj_signpost so it "just works" with the existing interaction code) whose interact_script is cis_npc_polyliner and then give it a new expression-typed variable "my_messages". For each sign you place you'd then give it a messages value like:
[tsprintf("This is %'s house!",global.player_name)]
(So it contains an array of strings, with only 1 value - this is different from just a regular string, since cis_npc_polyliner loops over the array of messages, so don't forget the []'s around it)
(The reason the default signpost doesn't work is that it has a string-type variable, so it'll just include the variable / tsprintf call as text instead of running the code. You could of course change it to expression-type in the base sign instead, but that breaks all existing signposts unless you manually add quotation marks around their text...)
put square brackets ([ at the start, ] at the end) around the resulting string?
The error message makes it sound like it's trying to interpret plaintext (the stuff that's supposed to be in a string) as an expression so it sounds like you missed the quotes.
Hello! Really looking forward to purchase this; however, i would like to know the platforms that this can run on? (Just PC? Or perhaps mobile, HTML5?) Thank you!
Could you explain how you have the imputs set up. I would like to add wasd controlls and controller. I also noticed that when you go diagnal you move faster so im trying to fix that.
Player movement is handled in Objects-->obj_player-->Step event. I think it's easiest if you add 4 new cases for up+left, up+right, down+left, down+right (which moves diagonally instead of just along x or y) and then use "else if" between all cases instead of just "if" so only one case can happen at once. (If you want to add diagonal sprites this approach will help too)
Do you run the k_u = gamepad code after the keyboard code, always? Because then you'll overwrite the keyboard values with the gamepad values (a variable can only have one value at a time)
If you want to support using both a keyboard and a gamepad at once, try OR'ing them together:
Okay i see. If i start the debugger i see that the global.input_key got a array (9560E80), but the global.active_game,global.input_pad a unable to evaluate.
This is the error i got:
ERROR in
action number 1
of Create Event
for object parent_menu:
trying to index a variable which is not an array
at gml_Script_get_keys (line 17) - k_u = keyboard_check(global.input_key[input_U]) ||gamepad_button_check(global.active_gamepad,global.input_pad[input_U])
My guess is that global.input_pad is not initialized to a value before you try reading it - did you add it to init_input? You'll need to define a gamepad input for every action (U/D/L/R/A/B/C/ST/SL).
I just bought this and it is by far the best purchase I've ever made for GMS2! Thank you for all the work you've done and for giving us the ability to buy it! I've been wanting an engine like this for so long but could never find one, but now I'll finally be able to make a great game! lol Thank you!
Thanks, glad you like the engine! Looking forward to see what you'll make with it! ^__^
One of my first (failed) GM projects back in the early 2000s was making a game in this style, but it just failed miserably... it felt great to finally be good enough at coding to tackle it :P
Well you did a great job with this! honestly it's worth more than what you're selling it for lol but it is always really nice to have it be affordable! I've been working on it with any free time I get and I was wondering, where would I go to change a monsters moves? I wasn't able to find it lol
Hello! I was wondering if this would also compile under the most current version of GMS2 on Mac? I'd love to purchase and look at the logic you're using for reference.
I have absolutely no idea, I don't have a mac and I don't have any intention of getting one any time soon. But none of the functions I've used are Windows-specific so it probably should just automagically work thanks to the GM sandboxing? (I'm really careful with those edge cases that breaks compatibility these days)
The one thing that could be an issue is the special rendering trick used to make you sink halfway through tall grass, but you could work around that by using draw_sprite_part and only draw half the player when you're in tall grass.
It Works Z I thought it was enter also I was wondering is there anyway I can email you, I was wondering if you ever planned on releasing your games on console I would honored if I can help & I have a proposal I want to discus with you, also is there any way to make the demo bigger screen wise
1. Any thoughts on how to restrict the types of stones to certain types. E.G. need fire stone to catch fire type creature?
2. How can we implement our own custom menus? From my search through the source, it looks to use some Draw GUI functions. I'm assuming I'd need to get rid of pretty much all menu options and develop my own menu from scratch with custom created images?
Thanks so much for everything. This project has really helped me develop my game over the past few months!
Glad the project has been useful to somebody! ^__^
For #1, the easiest option would be to have the stone type matchup affect catch rate directly. In init_items, change the argument for all monster stones to an array with two elements: catch rate, and a new type affinity parameter. Then in itemuse_catch, change line 13 from "argument1" to "argument1[0]" (reading the catch rate from the array) and add a new parameter for the catch rate as a multiplier for the final catch rate. For instance maybe you could write a function that, given an AMP ID and a type, returns either 1.00 if the monster has that type, or 0.05 (or even zero) if it doesn't, and then have the type parameter just be the elemental type that stone works on. (Or the factor could be based on something else entirely...)
Blocking the player from using the stone entirely if the monster doesn't have the type gets a slight bit more complicated, I think the easiest incision point would be in mev_battle_item_select. After you get the list of valid targets "targets" at line 6, go through the list and remove all targets whose type the stone doesn't work on, using whatever logic you are planning: hardcoded whitelists, type checks, level checks etc. (The selected item is in "my_item" at this point so you can access its data). Keep in mind, the list is an array and not a ds_list.
For #2, the GGUI code is so deeply ingrained in the menu functionality that it's probably going to be pretty difficult to replace it entirely. What exactly are you planning to do? It's made to be as generic as possible (with elements like frames and sprites that can use any assets you want) so it should be possible to script more or less anything with it. You can also add new element types by editing ggui_draw.
Okay, actually I'm just an executive hired programmer. I was hired to work with your job. She's amazing in many places. I was able to figure out how to do so to sort out all the monsters and much more .However, how could I do a batch-wide evolution check? I tried two ways, but it didn't work.
To evolve monsters, you need to take the following steps:
1) Store the player's current position (not necessary, but if you want them to be exactly where they were when you come back after the evolution, you should do this)
with(obj_player){
global.load_x = x
global.load_y = y
global.load_room = room
global.load_direction = drawdir
}
monamp = AMP index of monster to evolve - when you do a batch operation, you should loop over the AMP indexes you want to affect (e.g. entire player's party is from 0 to PARTYSIZE_ACTIVE; party + boxes is from 0 to PARTYSIZE_ACTIVE + PARTYSIZE_BOXED)
species = monster species to evolve into (the global array global.monster_evolution_mon has all the defined evolutions, but you can force a monster to evolve into any other species if you want)
AMP = Active Monster Party (aka, monsters that are currently loaded into the player party, an enemy party, or a storage box - it's different from the data about a monster species in general)
I am an adult gamer who works in IT and am dabbling in game creation. I have some changes I would like made for the game I am developing using this product. For example, the ability to set when certain creatures come out based on the time of day in-game. I would detail out the mechanics of how I would want it to work. You would provide me an estimate for each change I want made, and I would pay you half up-front via PayPal and half after each change is completed.
You may incorporate these changes into the product you have here on this page if you so want or provide me a set a scripts with the changes included, knowing that this code branch will not be maintained by you.
I'm not really interested. My day job keeps me in need of time more than money, and I'm already fully busy with my next new and exciting project. But if you have any questions about how to implement a new mechanic, feel free to ask it right here - I check my itchio notifications daily and try to answer every question!
Hi Yal, this looks amazing! It's exactly what I was looking for! My only question (for now) is can I have different sprites for different genders? Or will I have to create separate monsters to do that?
It should be relatively easy to add in... there's a question from a few weeks ago about having separate sprites for the front and back that goes more in-depth, but here's the cliff notes version:
monster_get_battlesprite is used to get the monster sprites, this uses the AMP ID of the monster to read sprites from so you could read its gender and then return different results if the species has separate male and female sprites.
These sprites would need to be added in init_monster (instead of just a map and battle sprite, you could have map + battle male + battle female, or even separate male and female map sprites), and of course this also means you need to modify init_monsters so that it gives the correct number of sprite arguments in each init_monster call.
To avoid having separate handling for monsters with and without gender differences (which makes things complicated...), I'd just have them always have separate male and female sprites in the code, but add the same sprite twice if there's no gender differences.
I'm having some trouble with this. It's probably my newb-ness. I'm trying to follow the example code that you gave in the previous comment, but I'm stuck. I think my problem is that I don't know where to put amp_GENDER to call it in monster_get_battlesprite. I'm declaring amp_GENDER in the init_constants. I want it to be 0=male and 1=female.
Could you help me with this? I apologize if I'm being dense.
So first of all, amp_GENDER would be an array index so it's only going to have a single value by itself... you should put it at this spot in init_constants:
Set it to the value of AMP_MAX (which is the first unused value for the AMP array index), then increase AMP_MAX by 1. While you're editing the init_constants script, also add in two new gender macros gender_MALE and gender_FEMALE (set to 0 and 1 as you wanted)
Next, go to amp_generate_monster (which sets up a newly spawned monster's AMP data) and add a new line like this:
This should make a newly spawned monster have a 50% chance to be male and a 50% chance to be female.
Finally, in monster_get_battlesprite, you'd get the gender via amp_read_var(argument0,amp_GENDER) and then have an if statement: if gender is equal to gender_MALE, return global.monster_data[amp_read_var(argument0,amp_MONID),mond_SPRITE_BATTLE_MALE], otherwise return global.monster_data[amp_read_var(argument0,amp_MONID),mond_SPRITE_BATTLE_FEMALE].
(Changing the battle sprite index in the monster data array so there's more than one was the stuff I told you about last time, and with this change we use both those new sprites)
Awesome, I got it working! I noticed, though, that it doesn't show the gender sprite when I look at my monster in the menu. Is there something I can change, for example in msh_spawn_monster_list, that will fix this?
Oh yeah, nice catch! Line 23 reads the sprite directly:
var spr = global.monster_data[global.active_monster_party[mon,amp_MONID],mond_SPRITE_BATTLE];
Changing this to
var spr = monster_get_battlesprite(mon);
should do the trick.
I did a quick search to see if there's any more direct reads that needs to be updated, there's a handful of other places where the sprite is read directly instead of using the monster_get_battlesprite script... searching for the string ",mond_SPRITE_BATTLE" (with the comma, but without quotes) should give you all the results so you can just click on them to instantly jump to the line that needs to be updated. You can ignore the starter select / nickname scripts and the moncyclopedia, but you probably want the shrine / terminal scripts, the evolution control, and normal nicknaming updated to use monster_get_battlesprite.
I'm sort of interested in messing around with this and creating an APK, just curious if this is portable to mobile or if it's relatively easy with the given asset pack. Thanks for your help.
I haven't tried (I don't own any of the GMS2 mobile export targets) but as far as I'm aware the engine doesn't use any Windows-specific functions.
I think the biggest stumbling block would be lack of touchscreen support... if you go with the "virtual gameboy buttons" approach a lot of the mobile emulators used to play Pokémon games seems to have picked (where there's a D-pad and A / B / Start / Select buttons on the screen and the rest doesn't respond to touching) this is probably not a huge issue, but if you want full touch support for menus, you're going to need to add that yourself.
On the plus side, all GUI elements are defined with basically the same logic and are put in a single array, so on a touch event (i.e., Global Mouse Pressed) you can basically loop through all elements in the currently active menu and see if any of them are in the target zone:
Thank you very much Yal for your response. I purchased this kit today to look into it. I was wondering if I could private message you a few questions on how to use this, and also had an idea on making a tutorial for others (unless there is one somewhere that I missed?).
Thank you for your response. I think ultimately I need to brush up on my GML and a few common uses in GM that I'm unfamiliar with.
I was trying to redesign the map, I was hoping to make a test level to travel around and experiment with but became easily lost in either GM or how things were placed. I understand the Overworld room and such, but much of it wasn't apparent to me.
I feel that my issues are only due to unfamiliarity with GM 2, and being really unfamiliar in general. Honestly, this was maybe a bit too ambitious for me and I'll have to revisit this once I've spent more time with other tutorials perhaps. My questions, even public, I feel are basic understanding that I don't yet have.
For example, if I rebuilt a map using the tiles provided. I don't know how to find the code that says after the visit with Professor to start in my test world instead.
Anyway, thank you for your time and thank you very much for this engine. I don't think I'm ready for this, but definitely something I will hang on to for further reference when I'm ready to take this on. Appreciate it!
As you wish! Making an RPG is complex business, and it probably pays off to familiarize yourself some more with GMS2 before jumping in at the deep end. The engine isn't going anywhere, so you can come back whenever you feel ready! ^__^
To answer your last few questions:
A lot of map objects - doors, NPCs, items - has their variables set via the new-in-GMS2 GUI variable system (double-click a trainer NPC and then click the "variables" button on the details window that pops up for an example).
The code that warps you to the starting map at the end of the intro is in script cc_intro_startgame (cc is "cutscene command"). You can get some examples of how to make cutscenes by checking out any cis_* script ("cutscene initialization script")
So I'm having a bit of trouble finding out how to make a monster evolve with the item evotype. How exactly does it work? Is it like the evolution stones in pokemon where you use them? Or do you need the monster to hold the item while it levels up? (I tried messing around trying to get both of these methods to work, but failed)
What should I be setting for type, validflags, use_script and use_arg for an evolution item in init_items?
I think I might've never implemented that and forgotten to remove the constant... but here's what I'd do.
Scripts --> Data Mangling --> Item Use Effect, create a new "itemuse_evolve" script. You can use itemuse_healHP as a guideline.
If in battle (check if room == rm_battle), the script does nothing and creates a message that you can't evolve a monster mid-battle. (With msh_itemuse_show_party_effects)
Otherwise, get the global.active_monster_party[monamp,amp_MONID] and store in a variable "species" - that's the species of the monster we're trying to use the item on.
Check all the global.monster_evolution_type / global.monster_evolution_arg belonging to this species, and schedule an evolution if we can find an item evolution that uses this particular item:
foundone = false;
for(var c = 0; c < global.monster_data[species,mond_TOTALEVOLUTIONS]; c++){
if(global.monster_evolution_type[species,c] == evotype_ITEM && global.monster_evolution_arg[ species,c] == my_item){
ds_queue_enqueue(global.pending_evolutions_queue,[monamp,global.monster_evolution_mon[ species,c]]);
inventory_lose_item(my_item,1); //Don't forget to consume the item
room_goto_fade_dontdestroy(rm_evolution,60);
foundone = true;
break;//We don't need to loop through more evolutions
}
}
if(!foundone){//Doesn't trigger an evolution for this species
msh_itemuse_show_party_effects("It wouldn't have any effect.")
}
Now you can define the item in init_items so that it uses the use_script itemuse_evolution, use_arg NONE, is of type itemtype_CONSUMABLE, has valid flags itemvalidflag_FIELD, and it should just magically work.
Oh, yeah - and you should also store the player's coordinates before changing rooms like when they enter a battle. You can copy the code from cc_battlestart_trainer (the "load_" variables)
For swapping two items, it's a bit complicated. I'm thinking it'd be easiest to duplicate inventory_lose_item into a new script called inventory_swap_item(itemID1, itemID2) and modify it so that it loops through the inventory twice, once for each item; once you have the two inventory slots, you just swap the ID/QTY data of those two slots using a temp variable.
Easy so far, but the tricky bit is GETTING the two item IDs you want to swap. If you want the Pokémon-style "press select" approach, I'm thinking you'd have some code in the script_step of the inventory menu (spawned by mev_pause_items / mev_battle_item) which checks for the 'select' button, and if so, memorizes the currently selected item (see mev_pause_items_select for an idea how to do that) spawns a new identical inventory menu (i.e. like in mev_pause_items / mev_battle_item) but uses NONE for its menu event script (the argument to msh_spawn_inventory) and another step script, which, if Select is pressed, memorizes the newly selected item, and if it's different from the first selected item, swaps the two items. In either case, it destroys itself, leaving you with the original inventory menu - but it should be updated to match the new sorting order, so you need to rebuild it. mev_pause_items_use_actually_use has a code snippet that rebuilds the item menu after the inventory potentially has changed, so apply that to the original inventory menu (easiest if you set the "daddy" variable of the "find the second item" inventory copy to the original inventory menu's id - just remember you'd loop over daddy instead of daddy's daddy when copying the code)
And of course, you might want a custom draw script for the "find the second item" menu that draws the inventory AND an extra marker for the first item, to notify the player that they're in a "rearrange the menu" state.
Side note: for multiple sorting options (e.g. A-Z, latest, etc) I'm thinking the easiest way would be modifying the msh_spawn_inventory_fill_list_category script, which builds a ds_list of all items of that "page" (items are actually stored in one big list internally instead of being divided into separate pages) - you could change that to a priority queue instead and have priorities based on the currently active sort mode.
mev_pause_items_use_actually_use has a code snippet that rebuilds the item menu after the inventory potentially has changed; copy that and use it to rebuild the menu whenever the player presses the "change sort mode" button. You could put this button check in the script_step of the affected menus, and note that you would apply the changes to the menu itself, not it's daddy's daddy, so remove the outer with loop.
This is definitely a noob question but I'm trying to add my own stuff, new types, new moves, new monsters, but whenever I am adding the line of code to either init_types, init_moves or init_monsters, the text for the new thing (type/move/monster) is blue instead of red like the other things and there's a yellow warning saying for example "variable type_DRAGON only used once" and the game does not Run when I try to test it. (and yes, they are in the exact same format as the type/move/monster, I copy pasted the line under the previous lines and just changed the stuff in them)
Is there somewhere else that I also need to define the new types/moves/monsters in order to get them to work or is there some other fundamental step that I am missing?
The types, monster IDs and so on are colored red because they're constants. You can add them in the init_constants script. This is where the type constants are defined, for instance:
(You can define constants anywhere in GMS2 but it felt easier to have them all in one place for easy access)
Keep two things in mind: each constant of each enumeration needs to have an unique value (e.g. type_DRAGON should have value 8), and you should update the MAX constant to be one higher than the highest constant (e.g. after adding the dragon type, TYPE_MAX should now be 9) so the loops that goes through some things won't skip the newly added data.
Hey Yal, thank you for your great work. i am a total noob in gms2 but with this it is easy to make a basic pokemon game. But i have one question: How can i use different battler sprites in front and back position and not only a mirrored sprite? For example, when the front name (enemy) has the name spr_001 and the back (your monster) spr_001_b? I think about to buy more assets from you, because you are a genius ;)
The easiest way would be to modify monster_get_battlesprite to return different sprites depending on whether the AMP ID is an enemy monster or not (right now it always returns the monster data mond_SPRITE_BATTLE column), player monsters would use a new mond_SPRITE_BATTLE_BACK sprite instead.
You can tell if an AMP ID is an enemy by checking if it's >= AMP_FIRST_ENEMY. If it's not, it's a player AMP ID. (If you're curious, AMP = Active Monster Party, the database of currently loaded monsters - player party, player boxes, and enemy party)
To add this new sprite data, you'd need to modify init_monster so that it takes three sprite arguments instead of two (currently it takes battle and map sprites, you'd want battle, battle_back and map), then update init_monsters (with an "s" at the end) so that it initializes the monsters with those three sprites instead of the current two.
thank you for your answer. have you got discord? i dont want to disturb you but i am new in game maker studio 2. i dont want to paste parts of your code here. maybe you can help me there. i can not run it.
Can't run it? What version of game maker are you using? There's separate GMS2.2 and GMS2.3 versions of the source file, so make sure you used the correct version (if you're on 2.3, the 2.3 source file contains some small changes/bugfixes from the 2.2 version that were necessary to make it compile )
oh it run perfectly. only after i tried to change monster_get_battlesprite, init_monster and init_monsters. there is an error (bug) in create_setup project. but thats my vault. i have to learn how to write GML. i have GMS2.3 from Steam Desktop.
Hi Yal, I'm a pretty big fan of yours, I've seen you so many times on here and on the gamemaker forums over the years.
I was wondering if you had some insight on the best way to customize this?
I'm wanting to learn from your engine and eventually make my own version of it from scratch, but for now I'm just attempting to get my proof of concept working using this.
I would like to use my own project and import your monster battling/collection system into it if possible, but the amount of scripts it has is a little overwhelming. I wouldn't know what to bring and what not to bring, yet at the same time, I find it somewhat difficult to import my project into this one and get everything working correctly.
Please let me know if you have any advice, thank you!
Edit: Hey so I decided to go from scratch and look towards you engine for occasional guidance.. Wish me luck!
obj_battlecontrol is the heart of the engine, I think its state machine contains almost half the code in the entire engine... but it's not quite enough to import it alone since it also communicates with the menus, the monster/move/party databases, and battle monsters and effects are their own objects.
There's a lot of dependencies between the different things in the engine, but I think something like this would be a good starting point if you want the entire battle system:
Everything in the "Battle" and "Menu" objects folders
The "Menu" objects have dependencies to the Menu Events, UI, and Drawing script folders
The "Battle" objects have dependencies to the Battle, Data Mangling and Effects script folders
There's a lot of misc dependencies to the "Maths n String Handling" scripts (in particular tsprintf is used everywhere)
Importing all of these would be a good starting point, and then test-playing to see if you get any "unknown function was called" errors - then you can make a judgment call if you'd want to import that script or replace the call with one of your existing ones (like the sound effect / music scripts - you probably have your own setup for that if you're partway through a large project).
Good luck! Feel free to ask any questions you're stuck on here, I try to check my Itchio notifications at least once per day.
Wow, thank you so much Yal! I think I will do this so that I can have a project with only the battling present, so that I can reference it easily. Thanks again!
Hi, Yal! I just bought the engine and it's looking awesome! I was wondering if there was a way to integrate turn-based cooldowns on abilities instead of of PP cost? Kind of like the pet battles in World of Warcraft. Thanks for all your hard work!
The easiest way would probably be to have PP regenerate by 1 every turn, and change the check whether the move has more than zero PP to check that it's entirely full. (Also you could reword the PP display when selecting the next attack so that it displays the number as either "ready" or as "X turns left", where X is max PP - current PP, e.g. how many more turns it takes for it to regenerate to full again)
Refilling PP probably would be easiest to implement in obj_battlecontrol's step event, state = ctst_ACTIONSELECT, substate = 0. (That's the start of the turn). Also, you'd probably want to add a case in the room transition when winning / losing a battle to refill all PP to max.
PP display GUI elements are set up in mev_battle_attack (starting at line 41) and mev_pause_monsters_status (starting at line 50).
The enemy PP check is at line 400 of the battle control's step event (state = ctst_ACTIONSELECT, substate = bcontrolstate_ACTIONSELECT_ENEMY). Player's PP check is mev_battle_attack at line 8.
Hey yal, I'm adding in a move speed stat for each move, with the intention of using it to multiply the user's speed so I can create a sort of move priority (with most moves having a move speed of 1 so it doesn't have any effect, but a quick attack-like move having a speed of 2 so the users speed is doubled when using it for who goes first calculations)
I'm just wondering if you know where is best to put it? at the moment I have changed line 421 in the battle control step event to:
but I get an error since a_comm isnt defined yet. I think this is because the engine doesn't actually check speed. on a turn by turn basis, right? So what I'm doing wouldn't be possible (at least the way I'm doing it). Any help would be much appreciated
Edit: just to let you know I have sorted the constants and everything else for move speed, as well as the init_move changes that were needed.
The ID of the move the enemy monster(s) picked is in the variable mv, which is defined at that point... so just change a_comm to mv and it should work as you intended. Speed is only checked when actions are slated / enqueued, they're sorted in a priority queue using the speed as priority and executed in that order.
It might be cleaner to add your speed variable to the case 30 block a bit further down, since that's where slated actions get finalized. There's a block here that lowers effective speed by -75% if the monster is paralyzed, and you could add in a new block that checks if the action type (battleaction_COMM_TYPE element of the array) is an attack, and if so, multiplies the SPEEDPRIO element with the move's speed. It shouldn't matter where you put this as long as it's before the "Finally, enqueue the action" bit, but it's probably safest to put it after the ailment block.
Thanks again, and actually that's a really good point. I suppose I need to consider how I wasn't paralysis to effect the overall priority, if it comes in after the move speed priority or before etc. Lots to think about. thanks again yal!
Hey Yal, is there any way to make a buff effect the user of the move whilst damaging the opponent? ie, you hit the opponent for x damage, then your speed gets buffed by 2?
There's no built-in "buff user" special effect type, so you'd need to add a custom one. The current buff special effect is handled in obj_battlecontrol's Step event at line 735-743, you'd copy that block to a new case in the switch statement that begins at line 780 (where effects that affect the user are handled). Just replacing the movespfx_BUFF constant in your new copy with the new constant, and changing all instances of the target variable trg to a_user in the new copy should be enough to make the code work.
Once all that is in place, just set your move's special effect to your new movespfx_BUFFUSER (and include the stat and buff tier like the existing buffs/debuffs) and you're good to go!
Oh maybe I'm not as stupid as I thought, cos I tried something super similar and couldn't get it to work, but I also made a custom barbs script for self buffin so it was a bit messier I suppose. Thanks for this Yal!
The freeze seems to be because the menu is destroyed with the default cancel, which doesn't advance the cutscene you're in. can_destroy is turned off just to prevent this by default, but you could add it in as a separate destroy script as a failsafe:
In msh_spawn_namingmenu at line 10, insert a new line:
script_destroy = csc_proceed;
Also insert the same line at line 3 in cc_shrinerename.
Now the menus should proceed the cutscene even if destroyed early.
For back sprites, there's a macro mond_SPRITE_BATTLE in init_constants. You'll want to add a new mond_SPRITE_BACK macro with an unique value, go to init_monster and add a new line after line 5:
Now go to init_monsters and add the back sprite to the array of sprites that get passed in for all monsters.
To actually read the battle sprite, I think the cleanest approach is to edit monster_get_battlesprite. Check if the AMP-ID passed in is in the "enemy" region ( >= AMP_FIRST_ENEMY), and if so return the mond_SPRITE_BATTLE sprite, otherwise return the mond_SPRITE_BACK sprite.
Thanks for the clear response. It helped get the freeze issue fixed but please note that applying the code to msh_spawn_namingmenu crashes the game as it affects the first naming menu.
I applied the fix in cc_shrinerename only. Problem solved.
Can you give me more guidance on the back sprite? For example how exactly do I
Check if the AMP-ID passed in is in the "enemy" region ( >= AMP_FIRST_ENEMY), and if so return the mond_SPRITE_BATTLE sprite, otherwise return the mond_SPRITE_BACK sprite.
The other thing I was vague about was where to add the back sprites. The init_monsters script has this place where we add an array of sprites for each monster:
Edit this and add a third "back" sprite after the map sprite. (Or before, if you prefer that, but then you'll need to make sure to adjust the changes I suggested for init_monster (without an "s" at the end) accordingly)
I'm using it to gauge what starter they selected in the following way, but no matter what starter I choose it returns the first option (I,e if I choose plaugsprout, they still summon Draquatic)
amp_has_monster just checks whether that AMP slot isn't empty. There's no script to check whether the player has a specific monster, so you'd need to make a new script with content along these lines:
///amp_player_owns_monster(monID)
//Returns true if the player owns at least 1 monster of the given species, false otherwise.
for(var c = AMP_FIRST_ACTIVE; c < AMP_FIRST_ACTIVE + PARTYSIZE_ACTIVE + PARTYSIZE_BOXED; c++){
if(global.active_monster_party[c,amp_MONID] == argument0){
return true;
}
}
return false
Using that script instead of amp_has_monster should give the result you want :)
thanks pally :) Trying to make someone with a tram reactive to what you pick. I guess another method could be to attach a flag to whatever starter is picked?
Thing about being able to check if the user has a monster tho is like you could have an artist who goes 'oh I want to paint a picture of monster_a, could you show me one?' and then if you have it you get a reward or something :)
Yeah, setting a flag in the menu event for selecting the starter would be the more robust option, since it will also work even if the player would release or trade away their starter, for instance - and you'd also not have to deal with extra cases for the starter's evolutions!
true true! in this case, it's for the first person the trainer fights in the game, so they probably couldn't trade it etc, but you're defo right long-term
← Return to asset pack
Comments
Log in with itch.io to leave a comment.
Hello. I have question. You can write in turn, as you have arranged these icons in the program?
-Poison - I understand...
-Bleeding - I understand...
-Blindness - I understand...
-Immolation - when someone is on fire? Good?
-Strain - I do not understand this! When is someone tired?
Or maybe stunned?
-Flinching - when is someone scared? Good?
-Paralysis - I understand...
???
This icons will be good?
I don't understand 5... "Strain". Could you explain to me? Because the translator translates it strange.
Strain = lose extra MP when doing a move. (I got the idea from Shin Megami Tensei). It's basically the "Spite" move from Pokémon, but as an ailment.
Like "Resentment" i think?
You think icon ZZZ is good for this?
or better this?
There will be a game when we finish ;)
https://husaria-games.itch.io/pixel-monsters
Second icon is more readable IMO, but it's your game :P
Yal... I have problem with add more monsters. I added 32 but in Monsterpedia (new name of my ...pedia) I have only 19 when I take this monster #macro monster_ORANGE_FOX 18 from start. When I take this monster for start #macro monster_FROG 22 i have 23. And when take this #macro monster_RABBIT 31 i have all 32. This 3 monsters these are the ones I choose at the beginning (NEW GAME).
Only shows me in MONSTERPEDIA these monsters before the one on the list + his.
EXAMPLE:
When I take #macro monster_HORSE 3 (number 3) I have in MONSTERPEDIA only 4 monsters:
#macro monster_HYENA 0
#macro monster_TIGER 1
#macro monster_GOAT 2
#macro monster_HORSE 3
Where is problem? :(
I make something like this:
On start Im take #macro monster_HYENA 0 (I have only HYENA in MOSTERPEDIA). I go fight. First monster with whom I fought it is #macro monster_BADGER 7. When I finish I have in MONSTERPEDIA 8 monsters (6 with "???" and HYENA and BADGER. Off course this "???" are a previous numbers of monsters before BADGER. And I go fight with another #macro monster_ELEPHANT 9. Now I have 10 monsters in MONSTERPEDIA. 7 with "???" (unknown) and 3 met by me.
These "???" these are the ones in front of the elephant. It should not immediately display a list of all that are added as unknown, ie with the characters "???"?Because he only adds when I get to know (the one I meet) and everything in front of him then (MACRO is about numbering), of course, those before the known (apart from those known) are marked with "???" that is, marked as unknown.
But it doesn't make sense. I think this is some kind of error or I am doing something wrong.
I changed your names to my monsters names. I checked everything 5 times. I missed nothing.
Nothing else I touched except the graphics.
And I check your demo. You have this same bug in it.
-------------------------------------------------------------
//Starters
#macro monster_HYENA 0
#macro monster_TIGER 1
#macro monster_GOAT 2
#macro monster_HORSE 3
#macro monster_SNAKE 4
#macro monster_COW 5
#macro monster_LION 6
#macro monster_BADGER 7
#macro monster_DONKEY 8
#macro monster_ELEPHANT 9
#macro monster_HIPPO 10
#macro monster_RHINO 11
#macro monster_DOG 12
#macro monster_CAMEL 13
#macro monster_POLAR_BEAR 14
#macro monster_CAT 15
#macro monster_OSTRICH 16
#macro monster_MOOSE 17
#macro monster_ORANGE_FOX 18
#macro monster_PIG 19
#macro monster_SHEEP 20
#macro monster_KANGAROO 21
#macro monster_FROG 22
#macro monster_GIANT_SNAIL 23
#macro monster_HEDGEHOG 24
#macro monster_PANDA 25
#macro monster_PLATYPUS 26
#macro monster_POLAR_FOX 27
#macro monster_SKUNK 28
#macro monster_SQUIRREL 29
#macro monster_TORTOISE 30
#macro monster_RABBIT 31
//Gotta enslave them all!
#macro MONSTER_MAX 300
#endregion
--------------------------------------------------------------
///cc_intro_startermonsterselect()
function cc_intro_startermonsterselect() {
var mon, mons, xx, ww;
mons = 3
mon[0] = monster_FROG
mon[1] = monster_ORANGE_FOX
mon[2] = monster_HORSE
ww = 1/mons
with(instance_create_depth(x,y,depth-1,obj_gguimenu)){
ggui_frame(VIEW_W*0.1,VIEW_W*0.35,VIEW_W*0.8,VIEW_H*0.25,NONE)//Yeah, we can do invisible frames!
ggui_menu_preallocate(mons,1)
ggui_element_text_settings(font_mainmsg,c_black,1,0)
for(var c = 0; c < mons; c++){
my_monster[c] = mon[c]
xx = (c + 0.5)*ww
ggui_element_sprite(xx,1.00,global.monster_data[mon[c],mond_SPRITE_BATTLE],0)
ggui_element_text( xx,1.05,global.monster_data[mon[c],mond_NAME])
ggui_menu_region(c,0,mev_intro_starterselect,xx - 0.5*ww,1 - ggui_frame_get_coord_y(128),xx + 0.5*ww,1)
}
menu_can_destroy = false
}
}
Only monsters you have seen get added to the list, it ends with the last monster you have registered:
If you want the entire list to be visible immediately, you could remove this loop and set maxmon to the value MONSTER_MAX-1 instead.
I was wondering do you plan to make a Yu-Gi-Oh type engine, card collection I think if you modified this one it might work into it
No plans, sorry. (The hardest part with making a collectible card game is making all the rules, and that's a very per-game-specific thing that's hard to make a general system for)
Understood
I'm just checking the update has the entire source code correct because I need to modify it, & you need to make some tutorials either a video with text or PDF so I can understand how to use it better thanks 👍
Yeah every update has the entire source code (it's the entire GameMaker:Studio project file)
Hey Yal, I'm wondering if you could help me on what to do for making moves that can do the following:
-Metronome like effect, completely random move
-A random move from a specific type (Example: Channel, uses a random Ghost type move)
I'd also like to make one that deals a random status effect, a random move from a list of specific moves, and a random stat lower or raise, but those ones I could probably figure out on my own once I know how to make those two. Also, I guess the metronome like move would need a blacklist so you don't pull out a boss-only move or something.
The answer to all of them basically boils down to "make a list of all moves and then pick a random entry from the list"... for very narrow categories you could build these lists manually, but for large lists (e.g. Metronome specifically) you could do this automatically: loop over all moves (after you've defined them in init_moves) and add the move ID to the list if it's valid (you could check validity using a new "valid for metronome" property, or your own list of invalid moves)
Now for the tricky part, when to do the table lookup and how to work it into the move system... I think this would be the easiest way:
Hey Yal, thanks a lot for this engine !
I'm actually trying to change how the battles works, but as a beginner I'm a bit lost on how the moves works.
Instead of the menu I would like to assign each attacks to one button, and the monster taking the damage if they were touched by an hitbox, but I don't really understand how to call for these moves. I guess it's about the amp_moves but I don't really know how.
sorry for the specific question ^^
Move IDs are stored in global.active_monster_party[amp_id,amp_MOVE1] through global.active_monster_party[amp_id,amp_MOVE4] and then move data is stored in the global.move_data array. So after you get a move ID from amp_MOVE1...amp_MOVE4 you can look up global.move_data using the ID you looked up and the move data constants (they begin with the prefix "mvd_")
Game Maker has support for networking, but I've never managed to get online multiplayer to work myself so I'm afraid I can't offer much help here.
Engine-wise I'm thinking you'd have the other player act like an AI player, and then their moves are based on what the player selects, with netcode synchronizing player inputs... you'll also need to make the RNG shared so things like variable damage and chance-based effects will be the same for both players.
I have several questions
1. how do I change what ev's a monster gives?
2. how do I make items that make specific monsters learn a move like tms?
3. is there a way to make monsters give less exp when deafeated?
4. I tried making battles 2v2 but right now if the player only has one the game crashes, and I couldn't get the enemy to have 2 without crashing
5. is there a wat to make a certain encounter with a monster have the monster have set ivs?
6. right now I can't find a way to view the move descriptions
7. how would I exclude some monsters from the monsterepeda?
8. I found a bug: after you run from a monster if you press the main button a bunch it will take you to the spot where the player character is in the room
9. how would I make a monster that evolves into 1 of 2 monster randomly?
10. is STAB implemented? and if not how can I put it in?
1. There's a stat for this in init_monsters, search for "mond_EVBONUS_STAT".
2. This is a bit tricky, but the basic steps would be:
- Create a new itemtype + usescript (check out init_items for the context for what these means) and add the new items to init_items
- The usescript first checks if the monster is compatible (if you want to have a check like this) and then does something similar to mev_monster_learnmove_spawnmenu (check out obj_battlecontrol's step event at line 1022 to see how it handles whether the monster has empty move slots and can learn moves immediately).
3. EXP calculations are done in obj_battlemonster's step event, line 94. Currently it's based on the monster's levelup EXP but you could add a new stat to the monster data for this for instance, or just lower the factor from 0.1 to something lower.
4. What's the crash error message? Player monster slots should start as KO'd if there's not enough monsters left that can fight, and you need to generate enough enemy monsters to fill all their slots. Check player_step_fill line 33 for how horde battles are generated currently.
5. Check out obj_npc_trainer's User Event 0, line 11 onwards it generates monsters. You could do something similar with a new "set encounter" object which generates new monsters and then overrides anything you want to change. (I assume you want to use this for legendaries so it'd also set the battle mode to wild instead of trainer)
6. It's currently only used in the learn new move menu (mev_monster_learnmove_spawnmenu), I guess I forgot to put it in when making the pause menu...
7. The easiest way would be like this:
- Add a new constant before MONSTER_MAX named MONSTER_PEDIA_MAX which has a lower value
- Go to mev_pause_moncyclopedia and change the first loop to end at MONSTER_PEDIA_MAX-1 instead of MONSTER_MAX
- Give all excluded monsters an ID number between MONSTER_PEDIA_MAX and MONSTER_MAX
8. I don't understand your explanation.
9. I think something like this could work:
- Create a new evolution type "evotype_RANDOM"
- Every monster that has this evolution type has an ARRAY of evolution monsters (third slot in the evolution data)
- amp_earn_exp checks for levelup evolutions, after line 40 add a new case that checks for evotype_RANDOM, and if the level requirement is met, sets evo to: global.monster_evolution_mon[ monid][c][irandom(array_length(global.monster_evolution_mon[ monid][c])-1)]
10. Yes, it's computed in the script compute_damage, line 50.
Man do you know How amazing you are?
This is perfect
How do I change the capture rate of each individual monster? and how to change how much exp each monster gives? also, how do I make battles have more monsters?
Is there by chance already a system to exclude encountering monsters that are currently in your party? I seen the possibility of doing something within the ects_placeholder function, but with out doing a bunch of if statements?
There's no built-in system, but it should be easy enough to set up.
In obj_player's collision event with obj_encounterzoneselector, after line 8 insert some new code:
(this is completely untested so use with care)
the encounter_valid_monsters array is common to all ects_* (EnCounter Table Setup) scripts so modifying it directly like this means it should work everywhere in the game.
Thank you. So far after testing it's worked perfectly. One more thing. What would best way to go about have a "Release Monster" from party in status menu? Thanks again for the help.
Call amp_clear_monster() on its AMP ID to reset a monster's data (AMP = Active Monster Party is the list of "currently loaded" monsters, e.g. party, boxes and enemies).
Sorry to bother you again, but still learning. I'm struggling on updating the monster part list. Maybe you can point me in the right direction on what I'm missing. This is what I have:
It looks pretty reasonable, but you both update and delete daddy.daddy... I think you meant this? (destroying the "are you sure?" menu and the "what do you want to do?" menu)
(also of course you need to set my_monster to the AMP_ID (index in the Active Monster Party array) of the monster you want to delete when you create the menu that eventually runs mev_pause_monsters_release_confirm() , so the variable has a valid value... I presume you're doing this?)
Well after further testing it does break after you catch all the possible monsters for that zone.
One way to fix that is to add some code setting the step range really high if the list of monsters is empty:
For additional stability, go to player_step_fill and add an if statement around line 10 to not count up encounter steps if the limit is 9999:
Thank you very much for all your help. That worked and was a much easier solution then what I was thinking.
Hey, how would I go about adding abilities to the game, for example stuff like Water Absorb that heals you when hit with a certain type of attack?
Easiest way would probably be to add a new argument to init_monster which is supposed to contain an array with at least four elements; trigger constant, trigger function, name string, and description string (the last two are optional but you probably want them for the status screen later), and then go through init_monsters and make sure every monster gets an ability. (Of course you need to define new "mond_" constants for these new data points and increase MONSTER_DATA_MAX accordingly, on top of adding the trigger constants and making some scripts)
The idea is that you add triggers wherever an ability could affect something: every turn, on damage, when first entering battle, etc. Check if the monster in question has the matching trigger constant, and if so, run its script. For your Water Absorb (and Flash Fire, Lightningrod, etc) example specifically, check out obj_damageapply's Alarm 0 event, near the bottom:
You'd basically want a check like this, but for the monster's ability instead of its item. (And since it might potentially cancel out damage, you want it at the TOP of the event instead - the "water absorb" ability effect script would set my_dmg to a negative value before it's applied, so it becomes healing)
Side note: if you want monsters to potentially have different abilities, you should also add ability slots to the "amp_" (Active Monster Party) system, and make amp_generate_monster pick a random ability out of the available choices from the species data (and of course, you look up AMP data instead of MOND data when you check if the ability applies). If you're gonna reuse abilities a lot you'd probably want to make a whole ability data array and have references to that instead of storing the entire trigger+script+name+description per-monster. But one step at a time!
Maybe a bit of a weirdly specific question, but I was thinking of pokemon like Spinda, where their markings are essentially randomly placed. Usually I would do this with a clipping mask and a random x and y coordinate when drawing the sprite, but I was curious if you knew off the top of your head if this would work? I would probably need to add the X and Y variable to the individual monster, and use that?
I think the easiest way to do things like this would be to expand global.monster_data and add a "draw script" field. Whenever the monster is drawn, invoke this script instead of just draw_sprite/draw_sprite_ext (you can find all cases where a monster is drawn by doing a project-wide search for the "mond_SPRITE_BATTLE" constant). For monsters that don't need any special drawing, you'd add a default script that just draws the sprite like normal.
This is gonna be a bit tricky since a lot of the drawing is in menus (shrine terminals, status screen etc) so you'd probably need to add a new type of GGUI element that contains both a sprite and a script to draw it with (right now monsters are drawn in menus by creating a sprite element containing their sprite).
For the random markings themselves, the easiest way would be to use random_set_seed() and construct the seed from something that's unique to the monster and won't change - e.g. some sort of hash of their IVs (or you could give them a new "ID number" field set to like, irandom(9999999) when generated with amp_generate_monster() if you think that's easier), then generate the random coordinates to draw with, and finally randomize() to reset the RNG again. This way, the random numbers will always be the same for the monster, but you don't need to store them in any way.
Thanks so much for all your super in depth answers, it's always helpful!
Curious because I couldn't see any built in function for it, what would be the easiest way to change text speed temporarily? To give the effect of someone speaking slowly, for instance.
Secondly, I don't see an easy way to do this in your code anywhere, so I was curious about "gift" monsters. I.E. an event that just straight-up gives one specific monster upon talking to someone.
Thanks again so much for your responses.
Gift monster ID's easier, so let's start with that.
Try amp_get_new_party_id to get the ID of the first empty slot in the party. If NONE, there's no empty slot - either abandon the gift procedure and tell the player they need to make some room in the party, or amp_get_new_box_id to get the first empty slot in the storage system instead. When you've got an empty slot, use amp_generate_monster to actually create a monster. (And optionally, give it a held item, special moves and so on - check out all the fun stuff in Scripts --> Data Mangling --> Active Monster Party). Also call msh_recompute_seencaught, in case the player didn't have this monster dex-ed yet.
(You can see an example of this stuff in action if you check mev_intro_starterselect_confirm.)
Now for text speed: There's two places where text speed is used, both in the message_handle script.
Line 17:
and line 23:
Depending on what needs you have, you could change either of those to put in some more speed control. I.e. instead of typing 2 + 2*k_a letters per step, you could type global.text_speed*(1 + k_a) letters, where the text speed variable defaults to 2 but there's a new "cc_textspeed" cutscene command script (see Scripts --> Cutscene System --> Cutscene Commands) which lets you change it at will. (I.e. change it to 1 to type more slowly, or change it to 99999 to reveal text instantly (but | characters can still be used to add dramatic breaks))
And of course, if you just want to add dramatic breaks or show someone enunciating a word extra clearly, there's no need for extra code - you could just sprinkle in some |s - one between each letter |l|i|k|e| |t|h|i|s, or a bunch at once when someone's...||| catching their breath.
Ahhhh thank you! Somehow I COMPLETELY missed the AMP scripts in data mangling, so I was just going around in circles for a few hours.
Curious if there's any breeding mechanic built in, or if it would be relatively easy to add one?
There's no breeding mechanic built in. It probably wouldn't be TOO hard to add one, but still pretty involved:
Is there a way to make a sign display the players name?
Yeah, just include the value of global.player_name in the message.
Easiest way would probably be to make a new type of signpost (a child of the obj_signpost so it "just works" with the existing interaction code) whose interact_script is cis_npc_polyliner and then give it a new expression-typed variable "my_messages". For each sign you place you'd then give it a messages value like:
(So it contains an array of strings, with only 1 value - this is different from just a regular string, since cis_npc_polyliner loops over the array of messages, so don't forget the []'s around it)
(The reason the default signpost doesn't work is that it has a string-type variable, so it'll just include the variable / tsprintf call as text instead of running the code. You could of course change it to expression-type in the base sign instead, but that breaks all existing signposts unless you manually add quotation marks around their text...)
Your the best thank you.
i get this when i do what you sugested.
Instance Code in Room: rm_overworld_5 at line 1 : invalid token '
Undefined variable 'This' referenced in room rm_overworld in instance inst_16EAE0C0's variable 'my_message'
Undefined variable 'is' referenced in room rm_overworld in instance inst_16EAE0C0's variable 'my_message'
Did you:
The error message makes it sound like it's trying to interpret plaintext (the stuff that's supposed to be in a string) as an expression so it sounds like you missed the quotes.
I copied exzactly what you had typed. Maby i missed where i need to change to an expresion var
It should look like this:
Hello! Really looking forward to purchase this; however, i would like to know the platforms that this can run on? (Just PC? Or perhaps mobile, HTML5?) Thank you!
There's no OS-specific functions used, but I haven't tried it on anything other than PC. (I only have a PC license of Game Maker)
Ok i might be dumb but i cant find the silly macro function fike :)
It's named "init_constants", should be right at the top of the Scripts folder.
Thank you. Always hard to learn aome one else code style the first time.
Could you explain how you have the imputs set up. I would like to add wasd controlls and controller. I also noticed that when you go diagnal you move faster so im trying to fix that.
So to change the default keys, you'd update init_input. To add alternate input like a controller, update get_keys.
E.g. instead of:
you might want something like:
(and so on for all other inputs)
Player movement is handled in Objects-->obj_player-->Step event. I think it's easiest if you add 4 new cases for up+left, up+right, down+left, down+right (which moves diagonally instead of just along x or y) and then use "else if" between all cases instead of just "if" so only one case can happen at once. (If you want to add diagonal sprites this approach will help too)
Thank you.
Hello,
I try to make the gamepad work, but i got some problems with it.
I hope you can help me out what i doing wrong.
What i did is the same like the keyboard check but then with the gamepad_button check.
like:
k_u = keyboard_check(global.input_key[input_U])
k_d = keyboard_check(global.input_key[input_D])
k_u gamepad_button_check(global.active_gamepad,global.input_pad[input_U])
k_d
gamepad_button_check(global.active_gamepad,global.input_pad[input_D])
ect.
Have i to change another script for make it work or doesn't work this like i did?
Thankyou.
Do you run the k_u = gamepad code after the keyboard code, always? Because then you'll overwrite the keyboard values with the gamepad values (a variable can only have one value at a time)
If you want to support using both a keyboard and a gamepad at once, try OR'ing them together:
Okay i see. If i start the debugger i see that the global.input_key got a array (9560E80), but the global.active_game,global.input_pad a unable to evaluate.
This is the error i got:
ERROR in
action number 1
of Create Event
for object parent_menu:
trying to index a variable which is not an array
at gml_Script_get_keys (line 17) - k_u = keyboard_check(global.input_key[input_U]) ||gamepad_button_check(global.active_gamepad,global.input_pad[input_U])
############################################################################################
gml_Script_get_keys (line 17)
gml_Object_parent_menu_Create_0 (line 4) - get_keys()//Get once so that held keys won't instantly trigger press-but-not-held
gml_Object_obj_gguimenu_Create_0 (line 2)
gml_Object_obj_titlescreen_Create_0 (line 2)
What is the best way to make the gamepad works? Thankyou for your answer.
My guess is that global.input_pad is not initialized to a value before you try reading it - did you add it to init_input? You'll need to define a gamepad input for every action (U/D/L/R/A/B/C/ST/SL).
Hello, i purchased this recently but i can't start the project it says:
___________________________________________
############################################################################################
ERROR in
action number 1
of Create Event
for object SETUP:
Pop :: Execution Error - Variable set failed argument - read only variable?
at gml_Script_tsprintf (line 8) - argument[0] = string_replace(argument[0],"%",string(argument[c]));
############################################################################################
gml_Script_tsprintf (line 8)
gml_Script_init_player_data (line 32) - global.monster_box_name[c] = tsprintf("Spirit Realm %",c+1)
gml_Object_SETUP_Create_0 (line 13) - init_player_data()
might be the new Update? well.. doesn't really matter if Version 2 or 3 i keep getting this and can't fix it myself
pls help
It seems like "argument" is read-only now, you can fix it by updating the script like this:
Thank you for the Update, haven't gotten the time yet to look into it before but it works now perfectly!
I just bought this and it is by far the best purchase I've ever made for GMS2! Thank you for all the work you've done and for giving us the ability to buy it! I've been wanting an engine like this for so long but could never find one, but now I'll finally be able to make a great game! lol Thank you!
Thanks, glad you like the engine! Looking forward to see what you'll make with it! ^__^
One of my first (failed) GM projects back in the early 2000s was making a game in this style, but it just failed miserably... it felt great to finally be good enough at coding to tackle it :P
Well you did a great job with this! honestly it's worth more than what you're selling it for lol but it is always really nice to have it be affordable! I've been working on it with any free time I get and I was wondering, where would I go to change a monsters moves? I wasn't able to find it lol
Open the script init_monsters and scroll to the right a bit, and you'll find this block of code:
Edit that :)
(Moves are pairs [LearnLevel, MoveID] and a learn level of NONE means the monster always starts with it known)
Okay thank you so much! You've done a lot to help everyone!
Hello! I was wondering if this would also compile under the most current version of GMS2 on Mac? I'd love to purchase and look at the logic you're using for reference.
I have absolutely no idea, I don't have a mac and I don't have any intention of getting one any time soon. But none of the functions I've used are Windows-specific so it probably should just automagically work thanks to the GM sandboxing? (I'm really careful with those edge cases that breaks compatibility these days)
The one thing that could be an issue is the special rendering trick used to make you sink halfway through tall grass, but you could work around that by using draw_sprite_part and only draw half the player when you're in tall grass.
I do not understand what is the difference between IV and EV.
The Demo wont work I press New Game Nothing
Did you press Enter? The game uses Z / X for the accept/cancel buttons.
It Works Z I thought it was enter also I was wondering is there anyway I can email you, I was wondering if you ever planned on releasing your games on console I would honored if I can help & I have a proposal I want to discus with you, also is there any way to make the demo bigger screen wise
Hi Yal!
Two questions for you:
1. Any thoughts on how to restrict the types of stones to certain types. E.G. need fire stone to catch fire type creature?
2. How can we implement our own custom menus? From my search through the source, it looks to use some Draw GUI functions. I'm assuming I'd need to get rid of pretty much all menu options and develop my own menu from scratch with custom created images?
Thanks so much for everything. This project has really helped me develop my game over the past few months!
Glad the project has been useful to somebody! ^__^
For #1, the easiest option would be to have the stone type matchup affect catch rate directly. In init_items, change the argument for all monster stones to an array with two elements: catch rate, and a new type affinity parameter. Then in itemuse_catch, change line 13 from "argument1" to "argument1[0]" (reading the catch rate from the array) and add a new parameter for the catch rate as a multiplier for the final catch rate. For instance maybe you could write a function that, given an AMP ID and a type, returns either 1.00 if the monster has that type, or 0.05 (or even zero) if it doesn't, and then have the type parameter just be the elemental type that stone works on. (Or the factor could be based on something else entirely...)
Blocking the player from using the stone entirely if the monster doesn't have the type gets a slight bit more complicated, I think the easiest incision point would be in mev_battle_item_select. After you get the list of valid targets "targets" at line 6, go through the list and remove all targets whose type the stone doesn't work on, using whatever logic you are planning: hardcoded whitelists, type checks, level checks etc. (The selected item is in "my_item" at this point so you can access its data). Keep in mind, the list is an array and not a ds_list.
For #2, the GGUI code is so deeply ingrained in the menu functionality that it's probably going to be pretty difficult to replace it entirely. What exactly are you planning to do? It's made to be as generic as possible (with elements like frames and sprites that can use any assets you want) so it should be possible to script more or less anything with it. You can also add new element types by editing ggui_draw.
Okay, actually I'm just an executive hired programmer. I was hired to work with your job. She's amazing in many places.
I was able to figure out how to do so to sort out all the monsters and much more .However, how could I do a batch-wide evolution check? I tried two ways, but it didn't work.
To evolve monsters, you need to take the following steps:
1) Store the player's current position (not necessary, but if you want them to be exactly where they were when you come back after the evolution, you should do this)
2) Put the monster in the evolution queue:
monamp = AMP index of monster to evolve - when you do a batch operation, you should loop over the AMP indexes you want to affect (e.g. entire player's party is from 0 to PARTYSIZE_ACTIVE; party + boxes is from 0 to PARTYSIZE_ACTIVE + PARTYSIZE_BOXED)
species = monster species to evolve into (the global array global.monster_evolution_mon has all the defined evolutions, but you can force a monster to evolve into any other species if you want)
3) Finally, go to the evolution room:
Thanks, it works.
How can I translate the prefix "amp"? I have a poor command of English culture, so it may not be obvious to me)
AMP = Active Monster Party (aka, monsters that are currently loaded into the player party, an enemy party, or a storage box - it's different from the data about a monster species in general)
Hi Yal,
Is there a maximum size for monster battle sprites?
Thanks!
Nope, you can go as high as you want. The menus resize the sprites so they'll fit in the allotted space, but it doesn't happen in battle.
That's what I needed to know. Thank you!
Hi Yal,
I am an adult gamer who works in IT and am dabbling in game creation. I have some changes I would like made for the game I am developing using this product. For example, the ability to set when certain creatures come out based on the time of day in-game. I would detail out the mechanics of how I would want it to work. You would provide me an estimate for each change I want made, and I would pay you half up-front via PayPal and half after each change is completed.
You may incorporate these changes into the product you have here on this page if you so want or provide me a set a scripts with the changes included, knowing that this code branch will not be maintained by you.
Please let me know if you are interested or not.
I'm not really interested. My day job keeps me in need of time more than money, and I'm already fully busy with my next new and exciting project. But if you have any questions about how to implement a new mechanic, feel free to ask it right here - I check my itchio notifications daily and try to answer every question!
Hi Yal,
Thank you for your reply! I'll let you know if I need help with certain mechanics.
Hope you have a good one!
Hi Yal, this looks amazing! It's exactly what I was looking for! My only question (for now) is can I have different sprites for different genders? Or will I have to create separate monsters to do that?
It should be relatively easy to add in... there's a question from a few weeks ago about having separate sprites for the front and back that goes more in-depth, but here's the cliff notes version:
To avoid having separate handling for monsters with and without gender differences (which makes things complicated...), I'd just have them always have separate male and female sprites in the code, but add the same sprite twice if there's no gender differences.
Hi Yal,
I'm having some trouble with this. It's probably my newb-ness. I'm trying to follow the example code that you gave in the previous comment, but I'm stuck. I think my problem is that I don't know where to put amp_GENDER to call it in monster_get_battlesprite. I'm declaring amp_GENDER in the init_constants. I want it to be 0=male and 1=female.
Could you help me with this? I apologize if I'm being dense.
So first of all, amp_GENDER would be an array index so it's only going to have a single value by itself... you should put it at this spot in init_constants:
Set it to the value of AMP_MAX (which is the first unused value for the AMP array index), then increase AMP_MAX by 1. While you're editing the init_constants script, also add in two new gender macros gender_MALE and gender_FEMALE (set to 0 and 1 as you wanted)
Next, go to amp_generate_monster (which sets up a newly spawned monster's AMP data) and add a new line like this:
global.active_monster_party[argument0,amp_GENDER] = choose(gender_MALE,gender_FEMALE)
This should make a newly spawned monster have a 50% chance to be male and a 50% chance to be female.
Finally, in monster_get_battlesprite, you'd get the gender via amp_read_var(argument0,amp_GENDER) and then have an if statement: if gender is equal to gender_MALE, return global.monster_data[amp_read_var(argument0,amp_MONID),mond_SPRITE_BATTLE_MALE], otherwise return global.monster_data[amp_read_var(argument0,amp_MONID),mond_SPRITE_BATTLE_FEMALE].
(Changing the battle sprite index in the monster data array so there's more than one was the stuff I told you about last time, and with this change we use both those new sprites)
Awesome, I got it working! I noticed, though, that it doesn't show the gender sprite when I look at my monster in the menu. Is there something I can change, for example in msh_spawn_monster_list, that will fix this?
Oh yeah, nice catch! Line 23 reads the sprite directly:
Changing this to
should do the trick.
I did a quick search to see if there's any more direct reads that needs to be updated, there's a handful of other places where the sprite is read directly instead of using the monster_get_battlesprite script... searching for the string ",mond_SPRITE_BATTLE" (with the comma, but without quotes) should give you all the results so you can just click on them to instantly jump to the line that needs to be updated. You can ignore the starter select / nickname scripts and the moncyclopedia, but you probably want the shrine / terminal scripts, the evolution control, and normal nicknaming updated to use monster_get_battlesprite.
I'm sort of interested in messing around with this and creating an APK, just curious if this is portable to mobile or if it's relatively easy with the given asset pack. Thanks for your help.
I haven't tried (I don't own any of the GMS2 mobile export targets) but as far as I'm aware the engine doesn't use any Windows-specific functions.
I think the biggest stumbling block would be lack of touchscreen support... if you go with the "virtual gameboy buttons" approach a lot of the mobile emulators used to play Pokémon games seems to have picked (where there's a D-pad and A / B / Start / Select buttons on the screen and the rest doesn't respond to touching) this is probably not a huge issue, but if you want full touch support for menus, you're going to need to add that yourself.
On the plus side, all GUI elements are defined with basically the same logic and are put in a single array, so on a touch event (i.e., Global Mouse Pressed) you can basically loop through all elements in the currently active menu and see if any of them are in the target zone:
Thank you very much Yal for your response. I purchased this kit today to look into it. I was wondering if I could private message you a few questions on how to use this, and also had an idea on making a tutorial for others (unless there is one somewhere that I missed?).
Feel free to ask any questions you might have here (if they're public, this means anyone that uses the engine can benefit from the answers).
Hello Yal,
Thank you for your response. I think ultimately I need to brush up on my GML and a few common uses in GM that I'm unfamiliar with.
I was trying to redesign the map, I was hoping to make a test level to travel around and experiment with but became easily lost in either GM or how things were placed. I understand the Overworld room and such, but much of it wasn't apparent to me.
I feel that my issues are only due to unfamiliarity with GM 2, and being really unfamiliar in general. Honestly, this was maybe a bit too ambitious for me and I'll have to revisit this once I've spent more time with other tutorials perhaps. My questions, even public, I feel are basic understanding that I don't yet have.
For example, if I rebuilt a map using the tiles provided. I don't know how to find the code that says after the visit with Professor to start in my test world instead.
Anyway, thank you for your time and thank you very much for this engine. I don't think I'm ready for this, but definitely something I will hang on to for further reference when I'm ready to take this on. Appreciate it!
As you wish! Making an RPG is complex business, and it probably pays off to familiarize yourself some more with GMS2 before jumping in at the deep end. The engine isn't going anywhere, so you can come back whenever you feel ready! ^__^
To answer your last few questions:
A lot of map objects - doors, NPCs, items - has their variables set via the new-in-GMS2 GUI variable system (double-click a trainer NPC and then click the "variables" button on the details window that pops up for an example).
The code that warps you to the starting map at the end of the intro is in script cc_intro_startgame (cc is "cutscene command"). You can get some examples of how to make cutscenes by checking out any cis_* script ("cutscene initialization script")
So I'm having a bit of trouble finding out how to make a monster evolve with the item evotype. How exactly does it work? Is it like the evolution stones in pokemon where you use them? Or do you need the monster to hold the item while it levels up? (I tried messing around trying to get both of these methods to work, but failed)
What should I be setting for type, validflags, use_script and use_arg for an evolution item in init_items?
I think I might've never implemented that and forgotten to remove the constant... but here's what I'd do.
Sorry for the inconvenience, I hope this helps.
How would you achieve an item sorting mechanism to manually rearrange items in the inventory? Any "easy" way under the engine conditions?
For swapping two items, it's a bit complicated. I'm thinking it'd be easiest to duplicate inventory_lose_item into a new script called inventory_swap_item(itemID1, itemID2) and modify it so that it loops through the inventory twice, once for each item; once you have the two inventory slots, you just swap the ID/QTY data of those two slots using a temp variable.
Easy so far, but the tricky bit is GETTING the two item IDs you want to swap. If you want the Pokémon-style "press select" approach, I'm thinking you'd have some code in the script_step of the inventory menu (spawned by mev_pause_items / mev_battle_item) which checks for the 'select' button, and if so, memorizes the currently selected item (see mev_pause_items_select for an idea how to do that) spawns a new identical inventory menu (i.e. like in mev_pause_items / mev_battle_item) but uses NONE for its menu event script (the argument to msh_spawn_inventory) and another step script, which, if Select is pressed, memorizes the newly selected item, and if it's different from the first selected item, swaps the two items. In either case, it destroys itself, leaving you with the original inventory menu - but it should be updated to match the new sorting order, so you need to rebuild it. mev_pause_items_use_actually_use has a code snippet that rebuilds the item menu after the inventory potentially has changed, so apply that to the original inventory menu (easiest if you set the "daddy" variable of the "find the second item" inventory copy to the original inventory menu's id - just remember you'd loop over daddy instead of daddy's daddy when copying the code)
And of course, you might want a custom draw script for the "find the second item" menu that draws the inventory AND an extra marker for the first item, to notify the player that they're in a "rearrange the menu" state.
Side note: for multiple sorting options (e.g. A-Z, latest, etc) I'm thinking the easiest way would be modifying the msh_spawn_inventory_fill_list_category script, which builds a ds_list of all items of that "page" (items are actually stored in one big list internally instead of being divided into separate pages) - you could change that to a priority queue instead and have priorities based on the currently active sort mode.
mev_pause_items_use_actually_use has a code snippet that rebuilds the item menu after the inventory potentially has changed; copy that and use it to rebuild the menu whenever the player presses the "change sort mode" button. You could put this button check in the script_step of the affected menus, and note that you would apply the changes to the menu itself, not it's daddy's daddy, so remove the outer with loop.
Thats actually really helpful and points me into the right direction. Many thanks for the detailed answer.
This is definitely a noob question but I'm trying to add my own stuff, new types, new moves, new monsters, but whenever I am adding the line of code to either init_types, init_moves or init_monsters, the text for the new thing (type/move/monster) is blue instead of red like the other things and there's a yellow warning saying for example "variable type_DRAGON only used once" and the game does not Run when I try to test it. (and yes, they are in the exact same format as the type/move/monster, I copy pasted the line under the previous lines and just changed the stuff in them)
Is there somewhere else that I also need to define the new types/moves/monsters in order to get them to work or is there some other fundamental step that I am missing?
The types, monster IDs and so on are colored red because they're constants. You can add them in the init_constants script. This is where the type constants are defined, for instance:
(You can define constants anywhere in GMS2 but it felt easier to have them all in one place for easy access)
Keep two things in mind: each constant of each enumeration needs to have an unique value (e.g. type_DRAGON should have value 8), and you should update the MAX constant to be one higher than the highest constant (e.g. after adding the dragon type, TYPE_MAX should now be 9) so the loops that goes through some things won't skip the newly added data.
Alright, thanks. I can't wait to play around with this.
Hey Yal, thank you for your great work. i am a total noob in gms2 but with this it is easy to make a basic pokemon game. But i have one question: How can i use different battler sprites in front and back position and not only a mirrored sprite? For example, when the front name (enemy) has the name spr_001 and the back (your monster) spr_001_b? I think about to buy more assets from you, because you are a genius ;)
The easiest way would be to modify monster_get_battlesprite to return different sprites depending on whether the AMP ID is an enemy monster or not (right now it always returns the monster data mond_SPRITE_BATTLE column), player monsters would use a new mond_SPRITE_BATTLE_BACK sprite instead.
You can tell if an AMP ID is an enemy by checking if it's >= AMP_FIRST_ENEMY. If it's not, it's a player AMP ID. (If you're curious, AMP = Active Monster Party, the database of currently loaded monsters - player party, player boxes, and enemy party)
To add this new sprite data, you'd need to modify init_monster so that it takes three sprite arguments instead of two (currently it takes battle and map sprites, you'd want battle, battle_back and map), then update init_monsters (with an "s" at the end) so that it initializes the monsters with those three sprites instead of the current two.
thank you for your answer. have you got discord? i dont want to disturb you but i am new in game maker studio 2. i dont want to paste parts of your code here. maybe you can help me there. i can not run it.
Can't run it? What version of game maker are you using? There's separate GMS2.2 and GMS2.3 versions of the source file, so make sure you used the correct version (if you're on 2.3, the 2.3 source file contains some small changes/bugfixes from the 2.2 version that were necessary to make it compile )
oh it run perfectly. only after i tried to change monster_get_battlesprite, init_monster and init_monsters. there is an error (bug) in create_setup project. but thats my vault. i have to learn how to write GML. i have GMS2.3 from Steam Desktop.
Hi Yal, I'm a pretty big fan of yours, I've seen you so many times on here and on the gamemaker forums over the years.
I was wondering if you had some insight on the best way to customize this?
I'm wanting to learn from your engine and eventually make my own version of it from scratch, but for now I'm just attempting to get my proof of concept working using this.
I would like to use my own project and import your monster battling/collection system into it if possible, but the amount of scripts it has is a little overwhelming. I wouldn't know what to bring and what not to bring, yet at the same time, I find it somewhat difficult to import my project into this one and get everything working correctly.
Please let me know if you have any advice, thank you!
Edit: Hey so I decided to go from scratch and look towards you engine for occasional guidance.. Wish me luck!
Thanks for the kind words! ^__^
obj_battlecontrol is the heart of the engine, I think its state machine contains almost half the code in the entire engine... but it's not quite enough to import it alone since it also communicates with the menus, the monster/move/party databases, and battle monsters and effects are their own objects.
There's a lot of dependencies between the different things in the engine, but I think something like this would be a good starting point if you want the entire battle system:
Importing all of these would be a good starting point, and then test-playing to see if you get any "unknown function was called" errors - then you can make a judgment call if you'd want to import that script or replace the call with one of your existing ones (like the sound effect / music scripts - you probably have your own setup for that if you're partway through a large project).
Good luck! Feel free to ask any questions you're stuck on here, I try to check my Itchio notifications at least once per day.
Wow, thank you so much Yal! I think I will do this so that I can have a project with only the battling present, so that I can reference it easily. Thanks again!
Hi, Yal! I just bought the engine and it's looking awesome! I was wondering if there was a way to integrate turn-based cooldowns on abilities instead of of PP cost? Kind of like the pet battles in World of Warcraft. Thanks for all your hard work!
The easiest way would probably be to have PP regenerate by 1 every turn, and change the check whether the move has more than zero PP to check that it's entirely full. (Also you could reword the PP display when selecting the next attack so that it displays the number as either "ready" or as "X turns left", where X is max PP - current PP, e.g. how many more turns it takes for it to regenerate to full again)
Refilling PP probably would be easiest to implement in obj_battlecontrol's step event, state = ctst_ACTIONSELECT, substate = 0. (That's the start of the turn). Also, you'd probably want to add a case in the room transition when winning / losing a battle to refill all PP to max.
PP display GUI elements are set up in mev_battle_attack (starting at line 41) and mev_pause_monsters_status (starting at line 50).
The enemy PP check is at line 400 of the battle control's step event (state = ctst_ACTIONSELECT, substate = bcontrolstate_ACTIONSELECT_ENEMY). Player's PP check is mev_battle_attack at line 8.
Hey yal, I'm adding in a move speed stat for each move, with the intention of using it to multiply the user's speed so I can create a sort of move priority (with most moves having a move speed of 1 so it doesn't have any effect, but a quick attack-like move having a speed of 2 so the users speed is doubled when using it for who goes first calculations)
I'm just wondering if you know where is best to put it? at the moment I have changed line 421 in the battle control step event to:
(monster_get_spd(action_monster.amp_id)*global.move_data[a_comm,mvd_MOVESPEED])
but I get an error since a_comm isnt defined yet. I think this is because the engine doesn't actually check speed. on a turn by turn basis, right? So what I'm doing wouldn't be possible (at least the way I'm doing it). Any help would be much appreciated
Edit: just to let you know I have sorted the constants and everything else for move speed, as well as the init_move changes that were needed.
The ID of the move the enemy monster(s) picked is in the variable mv, which is defined at that point... so just change a_comm to mv and it should work as you intended. Speed is only checked when actions are slated / enqueued, they're sorted in a priority queue using the speed as priority and executed in that order.
It might be cleaner to add your speed variable to the case 30 block a bit further down, since that's where slated actions get finalized. There's a block here that lowers effective speed by -75% if the monster is paralyzed, and you could add in a new block that checks if the action type (battleaction_COMM_TYPE element of the array) is an attack, and if so, multiplies the SPEEDPRIO element with the move's speed. It shouldn't matter where you put this as long as it's before the "Finally, enqueue the action" bit, but it's probably safest to put it after the ailment block.
Thanks again, and actually that's a really good point. I suppose I need to consider how I wasn't paralysis to effect the overall priority, if it comes in after the move speed priority or before etc. Lots to think about. thanks again yal!
Hey Yal, is there any way to make a buff effect the user of the move whilst damaging the opponent? ie, you hit the opponent for x damage, then your speed gets buffed by 2?
There's no built-in "buff user" special effect type, so you'd need to add a custom one. The current buff special effect is handled in obj_battlecontrol's Step event at line 735-743, you'd copy that block to a new case in the switch statement that begins at line 780 (where effects that affect the user are handled). Just replacing the movespfx_BUFF constant in your new copy with the new constant, and changing all instances of the target variable trg to a_user in the new copy should be enough to make the code work.
Once all that is in place, just set your move's special effect to your new movespfx_BUFFUSER (and include the stat and buff tier like the existing buffs/debuffs) and you're good to go!
Oh maybe I'm not as stupid as I thought, cos I tried something super similar and couldn't get it to work, but I also made a custom barbs script for self buffin so it was a bit messier I suppose. Thanks for this Yal!
Hi Yal
Thanks for this engine. I'm steadily working my way back to using Gamemaker thanks to it.
Please assist with these 2 queries:
The freeze seems to be because the menu is destroyed with the default cancel, which doesn't advance the cutscene you're in. can_destroy is turned off just to prevent this by default, but you could add it in as a separate destroy script as a failsafe:
In msh_spawn_namingmenu at line 10, insert a new line:
Also insert the same line at line 3 in cc_shrinerename.
Now the menus should proceed the cutscene even if destroyed early.
For back sprites, there's a macro mond_SPRITE_BATTLE in init_constants. You'll want to add a new mond_SPRITE_BACK macro with an unique value, go to init_monster and add a new line after line 5:
Now go to init_monsters and add the back sprite to the array of sprites that get passed in for all monsters.
To actually read the battle sprite, I think the cleanest approach is to edit monster_get_battlesprite. Check if the AMP-ID passed in is in the "enemy" region ( >= AMP_FIRST_ENEMY), and if so return the mond_SPRITE_BATTLE sprite, otherwise return the mond_SPRITE_BACK sprite.
Thanks for the clear response. It helped get the freeze issue fixed but please note that applying the code to msh_spawn_namingmenu crashes the game as it affects the first naming menu.
I applied the fix in cc_shrinerename only. Problem solved.
Can you give me more guidance on the back sprite? For example how exactly do I
Check if the AMP-ID passed in is in the "enemy" region ( >= AMP_FIRST_ENEMY), and if so return the mond_SPRITE_BATTLE sprite, otherwise return the mond_SPRITE_BACK sprite.
You'd do it like this:
The other thing I was vague about was where to add the back sprites. The init_monsters script has this place where we add an array of sprites for each monster:
Edit this and add a third "back" sprite after the map sprite. (Or before, if you prefer that, but then you'll need to make sure to adjust the changes I suggested for init_monster (without an "s" at the end) accordingly)
Hi Yal
Thanks again for extra info. Seems to have worked
Hey Yal... I'm so sorry to ask another question.
How does amp_has_monster work?
I'm using it to gauge what starter they selected in the following way, but no matter what starter I choose it returns the first option (I,e if I choose plaugsprout, they still summon Draquatic)
Thanks, and sorry again
if amp_has_monster(monster_DRACHNID) {
return [[monster_DRAQUATIC, 15, NONE, move_TACKLE, move_BOOMBUBBLE, move_DIVERGE,]]
}
if amp_has_monster(monster_PLAUGSPOUT) {
return [[monster_DRACHNID, 15, NONE, move_TACKLE, move_FIREWEB, move_DIVERGE,]]
}
if amp_has_monster(monster_DRAQUATIC) {
return [[monster_PLAUGSPOUT, 15, NONE, move_TACKLE, move_LEAFSHOT, move_DIVERGE,]]
}
amp_has_monster just checks whether that AMP slot isn't empty. There's no script to check whether the player has a specific monster, so you'd need to make a new script with content along these lines:
Using that script instead of amp_has_monster should give the result you want :)thanks pally :) Trying to make someone with a tram reactive to what you pick. I guess another method could be to attach a flag to whatever starter is picked?
Thing about being able to check if the user has a monster tho is like you could have an artist who goes 'oh I want to paint a picture of monster_a, could you show me one?' and then if you have it you get a reward or something :)
Thanks fer yer 'elp!
Yeah, setting a flag in the menu event for selecting the starter would be the more robust option, since it will also work even if the player would release or trade away their starter, for instance - and you'd also not have to deal with extra cases for the starter's evolutions!
true true! in this case, it's for the first person the trainer fights in the game, so they probably couldn't trade it etc, but you're defo right long-term