Comments

Log in with itch.io to leave a comment.

Back again as I am working on this more...question. Is there an easy way to implement a pause button? There doesn't seem to be one, though obviously I know the game CAN pause when you get  a level up for instance. What would be the quickest way to setup a "Press Button to Pause, Press again to Unpause"?

(2 edits) (+1)

Looking at the script room_enter_menu_maintaining_game_state should give you some ideas, it does a couple of things:

  • save the screen to a surface so the levelup menu can have the game in the background,
  • set the room to persistent, and
  • set up the player alarm which later turns off persistence again once you return to that room. (This alarm also is what applies all confirmed upgrades once you're back in the room)

After doing all that it changes the room to the one with the levelup menu - the game basically pauses by changing to a different room, but using persistence to maintain the state of the original room.

Also note obj_upgradecontrol, its regular Draw event draws this screenshot in the background (and then the menu is drawn on top), your pause menu would probably do something similar (or at least draw the screenshot + some static text that reads "paused")

As long as you make sure global.confirmed_upgrades is empty you should be able to just reuse this functionality wholesale (change rooms to the pause screen with room_enter_menu_maintaining_game_state, keep track which room you were in before you swap, and go back to that room when done), but the only things that really are needed are setting the room to persistent before you leave  and setting up an alarm to turn off persistence once you're back.

Thank you very much for your reply. If I may, I have another question. There are two things I want to do and I'm hoping you can help:


1) I want to be able to make each individual upgrade for weapons be the 'MaxUpgrades' amount rather than the sum of the upgrades. For example, let's say the default sword has a MaxUpgrades of 5. I could get 5 Whetstones, but no other upgrades. What I would like to do is be able to get 5 Whetstones, 5 Regimen, 5 Rage, ect.

2) This is a weird one. I see that you can use TriggerScripts for Weapon Upgrades, but I don't see examples for its usage, in weapons at least. What I wanted to do was max a unique upgrade for a weapon: Once gotten, it gains the ability to pierce, and then removes that upgrade from the potential future upgrades(as obviously you can't stack a true/false). I don't really see how to assign a variable to a specific weapon during a run, could I ask for your help?

(3 edits) (+1)

1) Currently in playerweapon_randomly_pick_some_random_upgrades (used to pick valid choices for levelups, chests etc) we check if a weapon hasn't reached max upgrade level with the line:

global.weapon_upgrades_obtained[c] < global.weapon_data[c][pstat_UPGRADESMAX]

To give each individual upgrade a separate counter you'd need to update both of these accordingly:

  • Make global.weapon_upgrades_obtained a 2D array where the second member has PWD_LOCALDATA_MAX elements that all are initialized to 0 at the start of a run, this is done in playerweapon_initialize_run.
  • In obj_player's Alarm 0 event, the UPGRADETYPE_UPGRADEWEAPON block, now you'd change the ++ line to instead increment global.weapon_upgrades_obtained[global.confirmed_upgrades[c][upgd_WEAPONINDEX]][global.confirmed_upgrades[c][upgd_INDEX]]
  • In the playerweapons script macro section (just before playerweapon_initialize_run) add a new constant dbupgd_MAXUPGRADES, for readability I recommend putting this as 0 and incrementing all other dbupgd_ stats by 1. Then at the start of every upgrade in the database, add the desired max level there. For instance the sword's upgradedata should now start off with [[5,[pstat_ATKPOWER,1],NONE,"Whetstone"...
  • In playerweapon_randomly_pick_some_random_upgrades now finally change the second term to global.weapon_data[c][pstat_POSSIBLEUPGRADES][d][dbupgd_MAXUPGRADES]

2) Yeah, currently triggerscripts are only used for things like the healing and money bag. I think the easiest way to implement this would be to make the actual update have no stat changes and no trigger script, and a max cap of 1 upgrades (see the answer to question 1) but the weapon's Player Shoot Script (e.g. pss_sword for the Hero Sword) checks if you have the upgrade, and if so alters the bullet's properties. The weapon script can check the variable currently_fired_weapon for the index in the player's active weapon list, and thus would check if global.weapon_upgrades_obtained[currently_fired_weapon][index_of_the_upgrade_in_the_list] > 0, for your convenience you'd probably want this upgrade to be first in the list so you don't need to count the already-confusing nested array slots.

I think for weapons using triggerscripts, you'd use them if the script does some one-off change that needs to work outside the weapon counter / PSS / stat system entirely, e.g. if the weapon creates a separate turret object rather than giving the player a weapon directly.

(1 edit)

Thank you for all your responces. I THINK I am following along so far, but the last element of Section 1 is throwing me off. What are you refering to be 'second term' in that function? Its not the argument I assume, so I'm not sure where to place that code. I've tried placing it as the second argument and setting 'include_weapons_we_have' to `global.weapon_data[c][pstat_POSSIBLEUPGRADES][d][dbupgd_MAXUPGRADES]`, but this does not work.


Edit: If by second term you meant of the initially referenced line, I changed it to the following:

`if((global.weapon_upgrades_obtained[c] < global.weapon_data[c][pstat_POSSIBLEUPGRADES][d][dbupgd_MAXUPGRADES]) || allow_surpassing_max_level){ //Can we upgrade it further?`

and got the following error, just in case

___________________________________________

############################################################################################

ERROR in

action number 1

of  Step Eventobj_player

for object parent_collectibleitem:

Push :: Execution Error - Variable Index [14] out of range [2] - -5.weapon_upgrades_obtained(100135,14)

 at gml_Script_playerweapon_randomly_pick_some_random_upgrades (line 97) -                             if((global.weapon_upgrades_obtained[c] < global.weapon_data[c][pstat_POSSIBLEUPGRADES][d][dbupgd_MAXUPGRADES]) || allow_surpassing_max_level){ //Can we upgrade it further?

############################################################################################

gml_Script_playerweapon_randomly_pick_some_random_upgrades (line 97)

gml_Script_ics_exp (line 23) -               playerweapon_randomly_pick_some_random_upgrades(3,true,true,global.player_level >= 3,global.player_level >= 3,true,false)

gml_Object_parent_collectibleitem_Collision_obj_player (line 3) -               collection_script()

Second term as in "global.weapon_data[c][pstat_UPGRADESMAX]".

Hmm, judging by the message everything wasn't set up as expected (the upgrades_obtained array is too short), it should be a two-dimensional array that's got as many slots on the first axis as the number of weapons the player can obtain, and the second axis should have PWD_LOCALDATA_MAX elements (now I'm realizing that's not actually correct, you want this number to be the max number of different upgrade choices any weapon can have - we're addressing by upgrade index and not by stat - but so far none of them has 12 upgrade paths so it should be fine).

But either way, global.weapon_upgrades_obtained should be at least a 6-by-12 element array, but it's only 2 elements along one axis, so something's weird there. The first step would be to print its contents with show_debug_message(global.weapon_upgrades_obtained) at the start of the function and see what's actually in it when the game crashes. (Note that it's not enough to just set array[5][11] to 0 when initializing it, that'll give you a 6 element array which contains a 12-element array in the 6th slot and the number 0 in the prior five slots - 2D arrays are just arrays of 1D arrays so if you want the inner arrays to have the same length you need to manually put one in every slot of the outer array)

Oh yeah, and another issue, you're checking global.weapon_upgrades_obtained[c], but you should check global.weapon_upgrades_obtained[c][d] because upgrade level is per-upgrade now instead of shared for the entire weapon. (You'll need to move this check into the loop over array_length(ups) as well)

Hi Yal, I've been going through the engine the last few days trying to understand and utilize some of it in my own survivors type game. For the most part its incredibly straightforward and easy to understand, but there are a few things here and there that I'm confused about and would love some clarification. Do you have a discord or anything like that?

I don't, but please ask any questions here and I'll answer them as soon as I'm able.

Hi Yal

I'm currently playing GP gun_10.  Could you tell me how many teleports there are because so far I found 6 (1,2,3,4,8,9).  I was in the Deep Cave and when I came back I lost a bat.  Is it possible to recover it?  Once I'm in the ruins of Bathville and I've found the key to the Sigma station, I can't go any further because when I fall down between two bats, I'm thrown into a room where all the doors are closed.  I was also looking for Waterfall, where there is supposedly some secret, but I don't know where it is

I'm asking for help because I'm starting to go crazy

Regard

s

Okay, in the playerweapons script, is global.weapon_data being initialized anywhere? 
I am getting the following error when trying to pick up an object that should in theory put a "knife" weapon in the our global.player_weapons array.

___________________________________________

############################################################################################

ERROR in

action number 1

of  Step Eventobj_player

for object obj_knife_pickup:

trying to index a variable which is not an array

 at gml_Script_playerweapon_register_new_scr_playerweapons_gml_GlobalScript_scr_playerweapons (line 309) -        array_copy(data,0,global.weapon_data[wid],0,PWD_LOCALDATA_MAX)

############################################################################################

gml_Script_playerweapon_register_new_scr_playerweapons_gml_GlobalScript_scr_playerweapons (line 309)

gml_Object_obj_knife_pickup_Collision_obj_player (line 7) -        playerweapon_register_new(wid_KNIFE)


The relevant knife data is filled out in playerweapons_init_all(). 

Any idea whats going on? 

playerweapons_init_all inits all the weapon data, normally it's created by the obj_setup (which sets up all the other data as well). Did you remove the blank first room that sets everything up (or change the starting room to a different one)?

global.weapon_data[wid] is probably what's not an array here, try printing it with a show_debug_message within playerweapon_register_new and it should tell you what it is (if it contains 'undefined' or crashes with an 'accessing array out of bounds' error you don't actually add the knife data as expected and then you most likely don't run the init script at all)

It would probably be possible to remove the playerweapons_init_all script entirely (code inside a script file but not inside a function body will be run when the game loads, this can be used to set up global variables earlier than normal and ensure that code is only ran once), the order of execution between different script files isn't guaranteed though so use with care.

(+1)

I'm running things from my own game, so I wasn't aware of that room actually. I'll take a look at that , thanks! 

probably something I am overlooking but I added a new player and then added a new button instance in the player select room but when I go into the room I get this error 

ERROR in

action number 1

of Other Event: User Defined 0

for object obj_keyboardmenucontroller:

Variable obj_playerselectbutton.menugridpos_x(100297, -2147483648) not set before reading it.

 at gml_Object_obj_keyboardmenucontroller_Other_10 (line 3) -        if(menugridpos_x == other.menugridpos_x && menugridpos_y == other.menugridpos_y){

############################################################################################

gml_Object_obj_keyboardmenucontroller_Other_10 (line 3)

gml_Object_obj_keyboardmenucontroller_Create_0 (line 18)


still kinda new to GM

(1 edit) (+1)

It's probably the order the Create Events run. The new button gets added at the end of the list, so it's not finished setting up when the keyboard menu controller's Create Event runs (it finds the currently hovered menu button by checking their "menu grid position" variables - but they don't exist until after the button objects have been properly created). You need to open the room's "Instance Creation Order" (there's a button in the inspector) and reorder things so the controller is created after all the buttons:


(There's a comment about having to do this in the create event of that object, but I maybe should've put it somewhere more visible...)

(+2)

Actually, I just realized there's an even better way to solve it - moving the "event_user(0)" from the Create event to the Room Start event (which runs after all create events have finished), that removes the creation order dependency entirely! Just cut and paste it into the indicated location:

I'll update the base download with this change as well so more people can avoid suffering.

(+1)

Ah your a lifesaver thanks

Do you think this would run on mobile okay?

(1 edit) (+1)

Even on my PC it gets slowdowns if you can survive long enough, but the main performance bottleneck is enemy-to-enemy collisions (where enemies are moved outside each other so you don't end up with a single 'conga line' blob) so you could get around that by focusing more on fewer stronger enemies instead of tons of weak enemies, or maybe change things around so each individual enemy object only collides with that one object, rather than the parent_enemy colliding with parent_enemy, so individual hordes keep their shape but they just phase through other groups.

So I bought the engine, but have a weird issue: I cannot get the source code to work...at all. I get prompted to create the folder, and it appears to do so, but I just get taken back to the start screen of GMS2. Trying to open  the created project file says that it failed the load the project. I'm using the GMS2-LTS, so I don't understand why I'm having issues with this project but no others. Anything come to mind?

(3 edits) (+1)

My guess is that it's created in a version newer than the LTS and something in the format has changed (I'm always on the latest version to find and fix issues with new features breaking my engines ASAP).

I know the new project loader was introduced recently-ish (version 2023.6, if memory serves) so potentially that's the issue, though the new format was made to be backwards-compatible so you'd think LTS could handle it... but it's almost a year old now so it might be lagging behind a bit...?

I asked around a bit and it sounds like you can have an LTS version and a regular version installed at the same time (as long as they're installed in different locations) so that could be a solution - having bleeding-edge for this engine and LTS for your other projects. (And having a beta and a regular version installed at the same time 100% definitely works)

Oh, that is interesting, and a bit unfortunate. I mostly stuck LTS since I thought it would be future proof as they described and I wouldn't have to deal with future version updates for the engine. Is there any chance there is some manner of converter for the project format? If I'm screwed I can probably just download a more recent version of GMS, I'm just hoping to avoid it if possible. I definitely understand it's not your fault though, unfortunate that LTS was broken as a 'stable' version so quickly though.

(1 edit) (+1)

As I said, you can have both LTS and a regular version installed at the same time without issues, they show up as different programs entirely. So no need to abandon LTS entirely.

LTS was released in late october 2022 (version number of the current LTS download is 2022.0.1.31 so it still appears to use the same version!) so it's about 10 months old at this point - it's lagging behind on features quite a bit and the timing of the new project format was quite unfortunate. I couldn't see anything about a new LTS release on the roadmap so presumably the next LTS release won't happen until the 2 years of support has passed? (in ~14 months from now) Scratch that, an upcoming update to LTS for the end of this month was announced today. No info what features from the bleeding edge will be ported over to LTS yet though...

In the worst case I suppose I could send you all the code as text files or something so you can paste it into a fresh project, but it'll be a pain to reassemble all the events and object relationships so I wouldn't really recommend this approach...

For up-to-date information on this stuff (LTS stability / project format queries) it's probably easiest to check in on the official forums, there's a shortcut to open the GMC in your browser from within Game Maker (Help --> Game Maker Community). I used to be a moderator but I've never been involved with actual GM software development so I have very little knowledge about how it works under the hood.

(+1)

Interesting that they happened to announce that today, what odd timing. So I downloaded the current beta for GMS2 and was able to open the project, edit files, ect.  I exported everything in the project into a local package- but trying to import it into an LTS project makes the program hang infinitely. The reason this is unfortunate is because I was hoping to make use of this engine as a Mini-Game within my main project which uses LTS.  I hope the update at the end of the month will make some magic happen somehow, until then I'll tinker around with it in the GMS2 BETA and just hope! I'm getting a feel for it and I really like how easy everything is to edit, as always, well done!

(+1)

Glad you figured out SOME way of opening it at last, at least... in the worst case, it's always possible to manually copy code from the GM Beta and recreate objects in the main project (should be a lot easier with two instances of GM so you can actually compare stuff properly, vs doing it by hand from the .gml / .yy files)

(The one thing that's not super obvious is that I use the GUI "Variables" interface for all the enemy stats, they're not set up by code in the Create event)

Hey, bought it and it is amazing, i am getting a lot of feather message errors, not to familiar with them but they won't cause anything to act up or break will they?

(+2)

It should be fine, Feather is more of a style guide and it complains about so many petty things it's almost unusable IMO.

(+1)

Exactly what I was looking for. Thanks. Now to learn how to make games.

I knew I'd forgotten something, the end-user license agreement - uploaded now. No surprises here, it's the same one I use for all other assets (don't resell the asset, but you can do whatever you want with a finished product made using it)

(+2)

You evil mastermind you. First off, I hate the game that I'm assuming inspired this as its art styles (there's multiple), fonts, and mechanics are extremely inconsistent. For some reason though, everyone enjoying the game just overlooks this. It kinda hurt's my eyes. But...., the fact that our favorite developer has made an engine that essentially gives ppl a chance to made their own (better) version of said game give me hope in the gaming space that we currently subside in.

10/10 will probably buy twice.
- LadiiPixel

It's pretty much become a genre at this point, hasn't it? I used to believe innovation stopped being a thing recently, we'd already threaded all the possible ground on gaming, so it's pretty cool seeing history happen before our own eyes.

I wasn't really planning on making this engine originally (conceptually it's not very challenging stuff going on behind the scenes) but I experimented a bit with making my own game for a jam and figured "heck, I've got some cool code here, might as well clean it up a bit and turn it into an asset". The biggest challenge really is GM's performance, the number of enemy-to-enemy collisions increase exponentially as the game goes on and it makes things go from smooth to unplayable very quickly once you hit the sweetspot.