A downloadable asset pack for Windows

Buy Now$14.99 USD or more

Yal's Monster Collector Engine is a GameMaker:Studio 2 project with all the tools you need to make a monster-collector RPG in the style of Pokémon / Digimon / Temtem / Telefang. The turn-based engine is supplemented with a solid database and GUI system that lets you easily script menus and manage data.

Try out the free demo if you want a first-hand taste of all the cool stuff this engine can do! It's got close to an hour of gameplay if you take your time and explore everything! :D

Features

  • Define a monster, item, move, or other database item with a single line of code! It's super easy to add content! Items and moves are based on extensible effect structures, and the engine comes with plenty of example items, monsters and moves to play around with!
    • Databases are set up using GML scripts - easy to change, and you get tons of color coding by default!
    • Each database entry is a single line in the script! All data is in one place, and it's super easy to add new monsters, moves, types and items!
    • Non-standard functionality is handled by script references, letting you offload as many complex special cases as you need to elsewhere in the codebase, keeping the database structured and clean!
    • Cutscenes uses a similar system where you enqueue script to be executed, each one with as many arguments as is needed! Just enqueueing messages is good enough to get information across, but you can get as advanced as you want!
  • Engine back-end code is only using the most basic GML functionality (arrays, loops etc) ensuring maximal compatibility between exports, and making the code  easy to read and understand! The code is also fully commented, with special tags to point out clever hacks and other parts that needs handling with care or are sensitive to changes.
  • The battle system supports an arbitrary amount of monsters on each side in battle! Do you think 1-on-1 battles is boring? How about making 2-vs-5 battles the new standard! You can have more monsters than fits on the screen if you want!
  • Moves, capturing monsters, battles etc  handles an arbitrary amount of monsters on each side just fine! You can even set the number of monsters on each side on a battle-per-battle basis, surprising the player with a 6-vs-1 horde battle in the middle of a dungeon for some extra challenge!
  • Newly caught monsters that don't fit in your party automatically gets sent to the storage system! Easily move monsters around between the active party and a number of storage boxes! (The number of storage boxes also can be set to any number you want - default 10 boxes of 40 monsters)
  • Supports as many savefiles as you want! (Default 99)
  • Easily set up monster trainers and other NPCs right in the room editor using the new GMS2 "variables" system! You don't even need to open a code editor, you just provide some monster data and dialogue data and then it's all set!
  • The engine automatically keeps track of both items and trainers! All you need to do is place them in a room, and the game will register them as defeated / collected automatically!
  • Simple system to connect different rooms with doors - doors just use two variables: a "label", and a room to transport the player to. The player is automatically placed next to the door with the matching label! Give your doors clear names like "shrine" or "freddy's house" instead of having to worry about their coordinates with pixel perfect precision!

It's Super Effective!

  • Traditional mechanics like move types being effective against certain monster types, held items having special effects, and monster trainers fighting you with a series of extra-strong monsters all are in place, and will work out of the box!
    • The held-item system has hooks set up at several points in the combat-turn flow, allowing you to run a script there to do whatever you want! Power up a monster's attack, heal it at the end of a turn, react to an enemy's attack, and more!
    • The type system allows an arbitrary number of types with extra damage, weakened damage, or downright immunity to other types! Add in that type you always wanted in the ultimate clash of elements, or settle down for a simple system that literally uses rock, paper and scissors!
  • Catch feral monsters, level them up, and watch them learn moves and even transform into new stronger species!
    • Monsters can automatically transform into a stronger species when their level is high enough! You just need to define the bond in the monster database, the engine handles the rest!
    • Monsters learn new attacks automatically, you just need to define it in the monster database!
    • Give your monsters nicknames to make them more relatable! Won't change anything gameplaywise, but it sure is fun!
  • The GoodGUI System from Yal's SoulsVania engine makes a return, making it easier than ever before to script your own menus! Plot out frames and fill them with content, and the menu contents will stay in position even if you resize the frames later! No need to manually tweak every coordinate to pixel precision!
  • Want to make a traditional RPG but feel RPG Maker is too limited? Just dummy out the monster-catching part and you've got a powerful turn-based battle engine to play around with!
  • Comes with graphics, music, sound effects, and monster data that can be used commercially! Use the engine for whatever you want, as long as you don't resell it (or parts / derivative works of it) as an asset pack!

(Note that this project is not compatible with GameMaker Studio 1.x)


Try it out!

There's a free demo of the project showing off all the features! Explore the first area, pick a starting monster, catch and train a party of local fauna, take in the tranquility of Driftwood City, and rise to the challenge of Fielder, the first League Master!

Demo controls:

Arrows - Move around / select stuff in menus

X - Select stuff / interact

Z - Cancel

StatusReleased
CategoryAssets
Rating
(3)
AuthorYal

Purchase

Buy Now$14.99 USD or more

In order to download this asset pack you must purchase it at or above the minimum price of $14.99 USD. You will get access to the following files:

Source Code (GMS2) (v.2) 26 MB

Download demo

Download
Demo 15 MB
Download
EULA 22 kB

Development log

Comments

Log in with itch.io to leave a comment.

(1 edit)

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.

(1 edit)

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.

(+1)

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!

(+1)

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:

  1. There seems to be a bug that freezes the game when you enter the menu to rename monster at the shrine but cancel without going through with it.
  2. How would I go about setting it so that the player uses "back-sprites" instead of inverted enemy sprites?

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:

global.monster_data[argument0,mond_SPRITE_BACK]    = argument2[2];

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.

(1 edit)

You'd do it like this:

if(argument0 >= AMP_FIRST_ENEMY){
  return global.monster_data[amp_read_var(argument0,amp_MONID),mond_SPRITE_BATTLE]
}
else{
  return global.monster_data[amp_read_var(argument0,amp_MONID),mond_SPRITE_BACK]
}


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)

(1 edit) (+1)

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:

///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 :)


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

Hey Yal. I'm back again, I am so so sorry for disturbing you but I got this thing bugging me and I can't figure it out. Basically, when my player object is beneath objects, it draws the head on the very top layer (I assume as part of how they are drawn in tall grass?) only problem is, I can't find where this is set to draw as the draw event contains only, as far as I can tell, the general drawing of the player sprite. I was figuring if I could locate the code that draws the head separately, I could add a:

if (place_meeting(x,y,obj_tallgrass_32) or place_meeting(x,y,obj_tallgrass_64) {

(the code that draws the head here)

}

so that when the player is below something say, a bridge on a higher layer, you don't see the head of the player. fake 3d, if you will!

Any help would be great, and hopefully it's not something obvious I've missed like a real dumbo the elephant.

Cheers Gov.

here's a pic, for clarity and what nots.

(+1)

Yeah, there's a reason why you find no special code for this in the player object: it's actually the grass that handles it. Basically, the grass is in front of the player normally, but each grass object draws the top of the player after drawing itself if the player currently is colliding with it. (Basically, I use the "painter's algorithm" to make part of the player be above the grass... by just drawing it on top of the grass)

(For some reason I use dynamic rendering masks for this - I just realized that just drawing the upper half of the player's sprite with draw_sprite_part would've probably done the same thing but with much simpler code... x3)

(+1)

On closer inspection, I just realized that this is a bug! The grass' drawing code uses || instead of && when doing the collision check, so essentially the player's status will always count as "in my particular patch of grass" and trigger the additional head drawing. Changing the the collision check ||s to && in obj_tallgrass_32's draw event (lines 13-16) should fix this. (obj_tallgrass_64 inherits everything from _32 so you shouldn't need to change that)

(+1)

Thanks again :) and woo hoo! My idiocy was useful!

(+1)

Fixed version is up! Thanks for the involuntary debug testing :3

(1 edit)

Hey Yal, I picked the engine up about a week ago and have been working my way through the code to understand it. Just gotten stuck on where / how you define at what level monsters 'transcend' and if there is an script to remove a monster from the player, eg so you could do one of those in-game trades with an npc where you remove the players monster then generate a new one based on whatever they're meant to get in return? Thank you so much :)

(1 edit)

Evolutions transcendences are defined at Scripts-->Data Mangling-->Database Setup-->Init Monsters, if you scroll to the right a whole bit you'll see this data:

(Basically it's an array of 3-member arrays, which represent the way to evolve, what thing triggers the evolution, and what monster to evolve to. For level evolutions, the trigger is the level to evolve at, for item evolutions it'd be the item ID, and so on... I'm unsure if I ever made item evolutions)


amp_clear_monster deletes a monster from the Active Monster Party (which is the big array that has all the monsters the player owns, including the storage boxes). Then you could use amp_generate_monster to create a new monster on the same AMP-ID, so it takes the exact slot the traded monster occupied. (Actually, you could just amp_generate_monster onto that slot directly, it clears the data with amp_clear_monster first). Once the monster is generated, you can manually apply unique quirks you want the traded monster to have (e.g. special moves or held items).

To get the AMP-ID of the monster to trade, I'd spawn a menu using msh_spawn_monster_list (which spawns a list of the monsters in the active party) which has a new "trade offer" menu event... it'd check if the monster in that slot matches what the NPC wants (that data would be stored in some global variables in the cutscene initialization script with the conversation) and if so, asks you a "ok?" question with msh_areyousure, and its OK script initiates the trade (sets the appropriate "trade done" flag, loads a different room with the trade animation, and then goes back).

If you need to familiarize yourself with how to carry data around, starting from mev_pause_monsters and looking into how the menus read party data further down the line should give you a good starting point in figuring out how to handle the AMP data (and the menu system in general).

Thank you so much Yal, it's amazing how intuitive your engine is, and how quick your support is! I can't believe I didn't scroll far enough to find the evo ttranscendences! I'm such a dolt! I thought of one last question, I'm so sorry to keep asking, but is there any way to set evolution moves? ie, a move it learns as soon as it evolves into charachne? Thanks again and so sorry for the questions! 

(2 edits) (+1)

Usually my support isn't that quick, I only check my itchio messages once per day... you just got lucky and posted that thing just a couple minutes before I happened to log in, gg :P

For evolution moves, it's going to be a bit messier since I didn't consider it when making the engine, but here's my idea:

In obj_evolutioncontrol, at line 73, add some extra code that checks if the newly evolved species (targevo) has any innate moves learned at level NONE. (Those are the moves they always know regardless of level). If there's any, attempt to learn them. The code of obj_battlecontrol's step event case 32 which handles newly learned moves (around line 1010) should be a good starting point for this new code (alongside with the code that sets the movelearn queue around line 997). It might be easier to add a new state to the evolution control's step event than trying to cram all this into case 20 where it waits for the menu objects to be done, just like how battle control uses one state to populate a queue and another state to read the next entry from the queue until it's empty.

With this system in place, you can define new moves learned on-evolution by adding innate moves to the evolved monsters which are learned on level NONE.

If you think the "level NONE" thing is a bit hacky and you want to fully separate always-known moves from on-evolution moves, add a new constant ON_EVO which is a value higher than your max level (e.g. 1000) and check for moves learned on that level in the evolution control instead of moves learned at level NONE. These moves can't be learned through levelling up, since the monster can't reach past the max level, so only the special case in the evolution control will do anything with the data.

Thank you again! Have a good day :)

(+1)

LOL re item evolutions: I just found the script for them and it's just '//todo' XD

(1 edit)

Hey! I just have a few questions to ask before buying. Hope it's ok:

How easy is it to change the resolution of the engine? Is their much tied to the resolution already or will there only be a few things I'd need to edit after changing it (I'm just thinking in my limited experience with GM that things like character speed would need to change, as well as any measuring etc) ?


How easy is it to change the animations for attacks, and the battle transitions etc?


Also, is there a grid movement system, and if not, do you think it'd be hard to add in?


thank you so much this looks amazing!

(+1)

Changing resolution should be fairly trivial, the battle controller sets things up based on the room size and most menus are defined in terms of two constants VIEW_W / VIEW_H. You'll need to manually change room sizes / viewports of every room in the game, but there's just a handful of rooms so it's hopefully not too much work.

Overworld character speed is defined in pixels per step, but it's just one variable you need to change in the player's create event. You might potentially also want to change the TILESIZE constant if you change the tileset size (this will have some ripple effects like grid sizes in existing rooms also having a different size, but I've never really tried changing a tileset size so I'm not 100% sure how much of that is automated)

Attack animations uses any object you want (typically a child of the effect parent), the battle flow waits until all effects are gone before proceeding. There's a convenience script fx_deferred_projectile which lets you spawn a standard projectile which runs another script on-hit (which works for a wide range of attacks) but you can add as intricate effects as you want if you feel like it.

The movement system isn't grid-based, but it shouldn't be too hard to add in. You'd basically turn the overworld player into a state machine with two states (idle and walking): in idle state, if any movement key is pressed, if whatever's one tile in that direction is OK to stand on: switch to walking state, start a countdown of TILESIZE, and start moving in that direction. In walking state, reduce the countdown, and when it hits zero, stop moving and switch back to idle state.

(+1)

thanks for all this, will probably pick it up in the morning :) cheers

(+1)

If you have any more questions about how to use it, you know where to find me :3

(+1)

While googling for some ideas to make a pokemon database, I came across this. And while I mostly understand arrays and such, I can't fully grasp them yet. Thank you for this code, I plan to build off it, or start from scratch after learning from yours to be used commercially. Your work looks fantastic. Thanks Yal.

(+1)

Thank you for the patronage and kind words! I'll be looking forward to hearing about great things from you once you get your game out there :)

(+1)

Every time I look you up there's a top-of-the-line asset to be found. I would have bought this day one had I known.

You can't keep getting away with this!

(+2)

Thanks for the kind words! ^__^

I'm slowly but surely running out of things I haven't done already, but I'll keep making new asset packs until GM is perfect :P

Deleted 213 days ago

Considering the sale ended 12 days ago, I feel like it would be unfair to everyone that has bought it in the meantime if I made a temporary discount just for you, even if you happen to be one of my most loyal customers. The monster collector engine release sale also lasted 1 week, instead of just 3 days which I usually use for release sales. There will be more Itchio sales, and I always join in when there is one, so just check back regularly and chances are you'll catch the next sale. (Itchio sends out e-mail notifications if you've got those turned on - I think it's possible to turn it up to max to get notifications whenever anyone you follow posts a new project, sale or a devlog on top of just the big site-wide announcements, too... if you do that, you'll never miss a sale again!)

You should also probably take some time to actually make a game with all those engines you bought too... Making 5 games at once tends to get pretty exhausting. :P

(+1)

Bought it right away, this asset is absolutely insane and safes so much time with the backbone for this kind of RPGs.

Is there a storage system (can't take a look at the code before tomorrow) included?

Keep up the good work, you are really one of my favourite GM devs.

(+2)

Thanks, glad you like it! ^__^

Monster storage system basically uses the gen3 system where you pick up monsters and move them around between boxes and the party. (Monsters caught when your party is full automatically is sent to storage). There's no item storage system, but you have infinite inventory space so that shouldn't matter (it's just more convenient now when you instantly have access to every item you own anyway).

(+1)

Thank you, missed that shrine as I played the demo. Its even more impressive now, the storage system works like a charm.

(you should mention that in the description, as this is a killer feature)

Good luck with your sales, its totally worth the price.

I'm pretty sure it's already in the description, but I guess I could give it more emphasis... the storage system wasn't all that much work to add in (most of the effort went into coding the menu for operating it), since the database is so optimized... but I guess that doesn't mean I can't tout it as a feature :P

(+2)

Ah! Another submission from you. Well done Yal!

(+1)

Thanks! ^__^ The "Dexit" debacle (and overall decline in quality in recent Pokémon games) made me think "meh, I could do this better"... so I figured I might as well actually do it :P

I probably didn't actually do it better, but this is just a small example project showing how it's done... most of the bulk of the work was setting up an easy-to-use database system, from my experiences that's the hardest part for an inexperienced user to get right, and if you get it wrong it can make it a real pain to work on the project later on. (Got some first-hand experience with that...)