Opry99er Posted April 20, 2015 Share Posted April 20, 2015 I have worked a total of a hundred plus hours over the last month on this menu functionality for my game development project... It has been quite a job, and it has been a whole lot of fun (and has been a true learning experience)... I am at the point where it works... almost perfectly. Here is a quick video of the menu in use, spells, items, everything except STATUS for which I have not made a video yet. http://www.youtube.com/watch?v=GHzi4lG3jAM I am at a point where I am going to try to declutter this code. There are some temporary variable sets in there that are technically global variable sets (big space eaters) and it is now fairly difficult to add or modify features because of the nature of the code itself. It is very easy for me to read (because I wrote it) but I want to post it here to get a sense of whether or not you can follow the program flow by reading the code... ****Yes... I know I have made a mistake by not implementing variable arrays from the start. There is a ton of this stuff that WILL get replaced by much more streamlined code, just by using 4 array sets for the variables...*** Matthew180 made a good point to me. When your code becomes difficult to modify and has too many global variables, it is probably a good sign that your design for flow and data handling is poorly constructed. That said, I am considering developing a new model for the data handling (multi-dimensional arrays and bottom-up menu construct). It's either that, or just modify what I've got to house those variables into arrays, streamline the subroutines to fit the new array sets, and eliminate a ton of unnecessary variables. Please look at this code if you get a moment. I am not good at indenting yet, but I have tried to do my best. See if this makes sense, and feel free to watch the video I posted above as a reference for what is happening in the various "compartments" of this menu. ***I have not included ALL the source for this game (like universal subroutines "ClearBox" and "ReturnString"). Just the menu code and one or two supporting subroutines for reference. Thank you in advance. //////////////////// //BEGIN MENU BLOCK// //////////////////// MainMenu: REM MENU CALL CLEAR :: CALL SCREEN(2):: CALL DELSPRITE(#1) CALL HCHAR(5,1,101,32):: CALL HCHAR(22,1,101,32):: CALL VCHAR(5,1,97,17):: CALL VCHAR(5,32,97,17) CALL HCHAR(5,1,98):: CALL HCHAR(5,32,100):: CALL HCHAR(22,1,99):: CALL HCHAR(22,32,96) MainMenu-MiddleReturn: GOSUB ClearMenu :: GOSUB ReturnString DISPLAY AT(1,14):"MENU";:: DISPLAY AT(2,14):"^^^^" DISPLAY AT(8,1):"1) ITEMS":"2) ARMOR":"3) WEAPONS":"4) SPELLS":"5) STATUS"; MidMenu-Keyscan: GOSUB Keyscan IF K=13 THEN CALL CLEAR :: GOTO DrawScreen !**BUG FIXED HERE** Case-sensitive labels IF K>54 THEN GOTO MidMenu-Keyscan ELSE IF K<49 THEN GOTO MidMenu-Keyscan ON K-48 GOTO ItemMenu,ArmorMenu,WeaponsMenu,SpellsMenu,StatusMenu //BEGIN Item Menu// ItemMenu: REM ITEM MENU GOSUB ClearMenu DISPLAY AT(1,12):"ITEMS";:: DISPLAY AT(2,12):"^^^^^" :: GOSUB ReturnString DISPLAY AT(8,1):"USE ON WHICH CHARACTER?";:"1) BERYL";:"2) REPTOSLICER";:"3) MARKUS";:"4) SKYLAR"; MidItem-Keyscan: GOSUB Keyscan IF K=13 THEN GOTO MainMenu-MiddleReturn IF K>52 THEN GOTO MidItem-Keyscan ELSE IF K<49 THEN GOTO MidItem-Keyscan ON K-48 GOSUB ItemBeryl,ItemRepto,ItemMarkus,ItemSkylar GOTO ItemMenu //ACN=name, ANSP=name starting point, ANL=name length// ItemBeryl: REM BERYL GOSUB ActiveBeryl GOSUB ItemMenu2 BHP=AHP :: BMP=AMP :: RETURN ItemRepto: REM REPTO GOSUB ActiveRepto GOSUB ItemMenu2 RHP=AHP :: RMP=AMP :: RETURN ItemMarkus: REM MARKUS GOSUB ActiveMarkus GOSUB ItemMenu2 MHP=AHP :: MMP=AMP :: RETURN ItemSkylar: REM SKYLAR GOSUB ActiveSkylar GOSUB ItemMenu2 SHP=AHP:: SMP=AMP :: RETURN REM **THIS IS THE MEAT OF THE ITEM MENU CODE** ItemMenu2: GOSUB ClearMenu :: DISPLAY AT(1,ANSP):ACN$;:: CALL HCHAR(2,ANSP+2,94,ANL) GOSUB ReturnString ItemDisplay: DISPLAY AT(8,1):"1) POTION";HPO;:"2) ETHER";MPO;:"3) ELIXIR";ELI; DISPLAY AT(3,1):"HP:";AHP;"/";AMHP;:: DISPLAY AT(3,16):"MP:";AMP;"/";AMMP; MidItem2-Keyscan: GOSUB Keyscan IF K=13 THEN RETURN IF K>51 THEN GOTO MidItem2-Keyscan ELSE IF K<49 THEN GOTO MidItem2-Keyscan ON K-48 GOSUB HealthPotion,MagicPotion,Elixir RETURN //Use HealthPotion// HealthPotion: IF HPO<1 THEN CALL SOUND(30,440,1):: HPO=0 :: GOTO ItemDisplay HPO=HPO-1 :: AHP=AHP+10 :: IF AHP>AMHP THEN AHP=AMHP GOSUB Flash GOTO ItemDisplay //used to be a "RETURN" here... changed to GOTO to facilitate multicasts RETURN //Use MagicPotion// MagicPotion: IF MPO<1 THEN CALL SOUND(30,440,1):: MPO=0 :: GOTO ItemDisplay MPO=MPO-1 :: AMP=AMP+10 :: IF AMP>AMMP THEN AMP=AMMP GOSUB Flash GOTO ItemDisplay //used to be a "RETURN" here... changed to GOTO to facilitate multicasts RETURN //Use Elixir// Elixir: IF ELI<1 THEN CALL SOUND(30,440,1):: ELI=0 :: GOTO ItemDisplay ELI=ELI-1 :: AHP=AHP+5 :: IF AHP>AMHP THEN AHP=AMHP AMP=AMP+5 :: IF AMP>AMMP THEN AMP=AMMP GOSUB Flash GOTO ItemDisplay //used to be a "RETURN" here... changed to GOTO to facilitate multicasts RETURN //END Item Menu// //////////////////////////////////////////////// // ARMOR AND WEAPONS MENUS NOT YET COMPLETE // //////////////////////////////////////////////// //BEGIN Armor Menu// ArmorMenu: REM ARMOR MENU GOSUB ClearMenu :: DISPLAY AT(1,12):"ARMOR";:: DISPLAY AT(2,12):"^^^^^" :: GOSUB ReturnString MidArmor-Keyscan: GOSUB Keyscan IF K=13 THEN GOTO MainMenu-MiddleReturn ELSE GOTO MidArmor-Keyscan GOSUB ClearMenu //END Armor Menu// //BEGIN Weapons Menu// WeaponsMenu: REM WEAPONS MENU GOSUB ClearMenu :: DISPLAY AT(1,11):"WEAPONS";:: DISPLAY AT(2,11):"^^^^^^^" :: GOSUB ReturnString MidWeapons-Keyscan: GOSUB Keyscan IF K=13 THEN GOTO MainMenu-MiddleReturn ELSE GOTO MidWeapons-Keyscan GOSUB ClearMenu //END Weapons Menu// //BEGIN Spells Menu// //////////////////////////////////////////////////////////////////////////////////////////////////// //SpellsMenu... this is a BIG one.... Need to have the ability to select WHO WILL CAST the magic/// //WHO WILL RECEIVE the magic, then display HP and MHP of receiver, MP and MMP of caster // //then animate the spell, display stat changes on both, then return to top of SpellsMenu. // //////////////////////////////////////////////////////////////////////////////////////////////////// SpellsMenu: REM SPELLS MENU GOSUB ClearMenu DISPLAY AT(1,12):"SPELLS";:: DISPLAY AT(2,12):"^^^^^^" :: GOSUB ReturnString DISPLAY AT(8,1):"WHO WILL CAST?";:"1) BERYL";:"2) REPTOSLICER";:"3) MARKUS";:"4) SKYLAR"; MidSpells-Keyscan: GOSUB Keyscan IF K=13 THEN GOTO MainMenu-MiddleReturn IF K>52 THEN GOTO MidSpells-Keyscan ELSE IF K<49 THEN GOTO MidSpells-Keyscan ON K-48 GOSUB CastBeryl,CastRepto,CastMarkus,CastSkylar GOTO SpellsMenu //////////////////////////////////////////////////////////////////////////////// //In the Castxxx section, program flow moves to the "Activexxx" subroutines // //Then to SpellsMenu2 (below) and then returns, updates the players' stats // //Then returns up to MidSpells-Keyscan once all that is complete. // //////////////////////////////////////////////////////////////////////////////// CastBeryl: GOSUB ActiveBeryl GOSUB SpellsMenu2 BHP=CHP :: BMP=CMP :: RETURN CastRepto: GOSUB ActiveRepto GOSUB SpellsMenu2 RHP=CHP :: RMP=CMP :: RETURN CastMarkus: GOSUB ActiveMarkus GOSUB SpellsMenu2 MHP=CHP :: MMP=CMP :: RETURN CastSkylar: GOSUB ActiveSkylar GOSUB SpellsMenu2 SHP=CHP:: SMP=CMP :: RETURN //**THIS IS WHERE THE CODE BEGINS TO GET A BIT CONVOLUTED, as two temporary variable sets are //**BEING USED TO DIFFERENTIATE BETWEEN CASTER AND RECEIVER... THIS IS WHERE THE ARRAYS WILL //**HELP SIGNIFICANTLY IN NOT ONLY REDUCING PROGRAM SPACE, BUT MAKING THIS WHOLE PROCESS //**MUCH MORE UNDERSTANDABLE TO MYSELF AND OTHERS. SpellsMenu2: //this part loads the "C" temporary variable set (caster) with the info from the "A" temporary variable set (active) CMMP=AMMP :: CMP=AMP :: CHP=AHP :: CMHP=AMHP :: CP$=ACN$ :: CNSP=ANSP :: CNL=ANL ::CMN=AMN //Display Caster's info at the top of the screen// GOSUB ClearMenu :: DISPLAY AT(1,CNSP):CP$;:: CALL HCHAR(2,CNSP+2,94,CNL) DISPLAY AT(3,1):"HP:";CHP;"/";CMHP;:: DISPLAY AT(3,16):"MP:";CMP;"/";CMMP; GOSUB ReturnString IF CMN=0 THEN DISPLAY AT(17,1):"THIS MEMBER CANNOT CAST" :: GOSUB Keyscan :: GOTO SpellsMenu DISPLAY AT(8,1):"CAST ON WHICH PARTY MEMBER?";:"1) BERYL";:"2) REPTOSLICER";:"3) MARKUS";:"4) SKYLAR"; MidSpells-Keyscan2: GOSUB Keyscan IF K=13 THEN GOTO SpellsMenu IF K>52 THEN GOTO MidSpells-Keyscan2 ELSE IF K<49 THEN GOTO MidSpells-Keyscan2 ON K-48 GOSUB ReceiveBeryl,ReceiveRepto,ReceiveMarkus,ReceiveSkylar GOTO SpellsMenu ////////////////////////////////////////////////////////////////////////////// //this is where changes have been made to allow multiple casts on one player// ////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //In the Receivexxx section, program flow moves to the "Activexxx" subroutines// //Then to SpellsMenu3 (below) and then returns, updates the players' stats // //Then returns up to MidSpells-Keyscan2 once all that is complete. // //////////////////////////////////////////////////////////////////////////////// ReceiveBeryl: GOSUB ActiveBeryl GOSUB SpellsMenu3 BHP=RPHP :: RETURN ReceiveRepto: GOSUB ActiveRepto GOSUB SpellsMenu3 RHP=RPHP :: RETURN ReceiveMarkus: GOSUB ActiveMarkus GOSUB SpellsMenu3 MHP=RPHP :: RETURN ReceiveSkylar: GOSUB ActiveSkylar GOSUB SpellsMenu3 SHP=RPHP:: RETURN SpellsMenu3: //this part loads the "RP" temporary variable set (receiver) with the info from the "A" temporary variable set (active) RPMMP=AMMP :: RPMP=AMP :: RP$=ACN$ :: RPNSP=ANSP :: RPNL=ANL :: RPHP=AHP :: RPMHP=AMHP GOSUB ClearBox //Display Receiver's Name and stats INSIDE the box// DISPLAY AT(8,RPNSP):RP$;:: CALL HCHAR(9,RPNSP+2,94,RPNL) DISPLAY AT(10,1):"HP:";RPHP;"/";RPMHP;:: DISPLAY AT(10,16):"MP:";RPMP;"/";RPMMP; DISPLAY AT(12,1):"CAST WHICH SPELL?" IF CMN=3 THEN GOSUB ReptoFinalCast IF CMN=2 THEN GOSUB SkylarFinalCast IF CMN=1 THEN GOSUB BerylFinalCast RETURN //////////////////////////////////////////////////////////////////////////////// //In the xxxFinalCast section, the program looks for a keypress, then branches// //to "which spell was cast" below... Each spell carries with it a MP cost for // //the casting party member and a HP gain (and status change in the case of // //the LIFE spell) for the receiving party member... // //////////////////////////////////////////////////////////////////////////////// ReptoFinalCast: DISPLAY AT(15,1):" " DISPLAY AT(16,1):"1) HEAL (10 MP)";:"2) CURE (15 MP)";:"3) LIFE (20 MP)"; :: GOSUB Keyscan IF K=13 THEN RETURN IF K>51 THEN GOTO ReptoFinalCast ELSE IF K<49 THEN GOTO ReptoFinalCast ON K-48 GOSUB HealSpell,CureSpell,LifeSpell RMP=CMP GOTO ReptoFinalCast //***THIS WAS CHANGED FROM "RETURN" TO "GOTO xxxFINALCAST IN ORDER TO FACILITATE MULTICASTS" SkylarFinalCast: DISPLAY AT(15,1):" " DISPLAY AT(16,1):"1) HEAL (10 MP)";:"2) CURE (15 MP)"; :: GOSUB Keyscan IF K=13 THEN RETURN IF K>50 THEN GOTO SkylarFinalCast ELSE IF K<49 THEN GOTO SkylarFinalCast ON K-48 GOSUB HealSpell,CureSpell SMP=CMP GOTO SkylarFinalCast //***THIS WAS CHANGED FROM "RETURN" TO "GOTO xxxFINALCAST IN ORDER TO FACILITATE MULTICASTS" BerylFinalCast: DISPLAY AT(15,1):" " DISPLAY AT(16,1):"1) HEAL (10 MP)"; :: GOSUB Keyscan IF K=13 THEN RETURN IF K=49 THEN GOSUB HealSpell ELSE GOTO BerylFinalCast BMP=CMP GOTO BerylFinalCast //***THIS WAS CHANGED FROM "RETURN" TO "GOTO xxxFINALCAST IN ORDER TO FACILITATE MULTICASTS" ////////////////////////////////////////////////////////////////////// //**Need to add status flag for "Healthy" "Poisoned" and "Fallen" // //**As of now, Cure and Life do not do all that they WILL do once // //**this is implemented fully. Cure will heal "Poisoned" and change// //**status flag to "Healthy," Life will change status from "Fallen" // //**To "Healthy" and will allow "Heal" magic to raise HP. // ////////////////////////////////////////////////////////////////////// HealSpell: IF CMP<10 THEN GOSUB ClearBox :: DISPLAY AT(15,1):"NOT ENOUGH MP"; :: GOSUB Keyscan :: GOTO SpellsMenu IF RPHP<1 THEN GOSUB ClearBox :: DISPLAY AT(15,1):"MEMBER IS FALLEN"; :: GOSUB Keyscan :: RETURN CMP=CMP-10 :: RPHP=RPHP+10 :: IF RPHP>RPMHP THEN RPHP=RPMHP GOSUB SpellResult RETURN //This will also change the status flag to "Healthy" once that part is complete CureSpell: IF CMP<15 THEN GOSUB ClearBox :: DISPLAY AT(15,1):"NOT ENOUGH MP"; :: GOSUB Keyscan :: GOTO SpellsMenu CMP=CMP-15 GOSUB SpellResult RETURN //Still Need to add status flag for "Healthy" "Poisoned" and "Fallen" LifeSpell: IF CMP<20 THEN GOSUB ClearBox :: DISPLAY AT(15,1):"NOT ENOUGH MP"; :: GOSUB Keyscan :: GOTO SpellsMenu IF RPHP<1 THEN RPHP=1 :: GOTO LifeSpellEnd RPHP=RPMHP LifeSpellEnd: GOSUB SpellResult RETURN SpellResult: ///**bug**////// //////////////// //when casting// //on ones self// //RP is not // //updated when// //spell is cast/ //////////////// ////**bug**///// DISPLAY AT(3,1):" " DISPLAY AT(3,1):"HP:";CHP;"/";CMHP;:: DISPLAY AT(3,16):"MP:";CMP;"/";CMMP; DISPLAY AT(8,1):" ":" ":" " DISPLAY AT(8,RPNSP):RP$;:: CALL HCHAR(9,RPNSP+2,94,RPNL) DISPLAY AT(10,1):"HP:";RPHP;"/";RPMHP;:: DISPLAY AT(10,16):"MP:";RPMP;"/";RPMMP; GOSUB Flash CALL SOUND(50,330,1) :: CALL SOUND(50,494,1) :: CALL SOUND(100,1319,0,494,10,330,10) RETURN /////////////////// //END Spells Menu// /////////////////// //REM STATUS MENU// //REM THIS IS THE NEXT AREA OF FOCUS... GET WORKING STATUS MENU GOING BY LOADING THE "A" SET WITH CHAR'S INFO// //REM **USE THESE: ALEV=BLEV :: AMHP=BMHP :: AHP=BHP :: AMMP=BMMP :: AMP=BMP :: ADEF=BDEF :: AATK=BATK :: AMDEF=BMDEF// //REM **AMATK=BMATK :: ACN$="BERYL" :: ANSP=14 :: ANL=5// StatusMenu: CALL DELSPRITE(#1) GOSUB ClearMenu :: DISPLAY AT(1,12):"STATUS";:: DISPLAY AT(2,12):"^^^^^^" :: GOSUB ReturnString DISPLAY AT(8,1):"WHICH CHARACTER?";:"1) BERYL";:"2) REPTOSLICER";:"3) MARKUS";:"4) SKYLAR"; CALL MAGNIFY(1) MidStatus-Keyscan: GOSUB Keyscan IF K=13 THEN GOTO MainMenu-MiddleReturn IF K>52 THEN GOTO MidStatus-Keyscan ELSE IF K<49 THEN GOTO MidStatus-Keyscan GOSUB ClearBox ON K-48 GOSUB StatusBeryl,StatusRepto,StatusMarkus,StatusSkylar GOTO StatusMenu /////////////////////////////////////////////////////////////////////////////////// //In the Statusxxx section, the program displays the character's name, underlines// //it, draws the character's likeness onscreen with a SPRITE, then branches to // //StatusDisplay, where the character's data will be displayed onscreen as well // /////////////////////////////////////////////////////////////////////////////////// StatusBeryl: GOSUB ActiveBeryl DISPLAY AT(7,7):"BERYL REICHARDT";:: DISPLAY AT(8,7):"^^^^^^^^^^^^^^^" CALL MAGNIFY(3) :: CALL SPRITE(#1,132,9,120,200) GOSUB StatusDisplay RETURN StatusRepto: DISPLAY AT(7,9):"REPTOSLICER";:: DISPLAY AT(8,9):"^^^^^^^^^^^" GOSUB ActiveRepto CALL MAGNIFY(3) :: CALL SPRITE(#1,136,3,120,200) GOSUB StatusDisplay RETURN StatusMarkus: DISPLAY AT(7,5):"MARKUS THE VALIANT";:: DISPLAY AT(8,5):"^^^^^^^^^^^^^^^^^^" GOSUB ActiveMarkus CALL MAGNIFY(3) :: CALL SPRITE(#1,124,5,120,200) GOSUB StatusDisplay RETURN StatusSkylar: DISPLAY AT(7,7):"SKYLAR TWILIGHT";:: DISPLAY AT(8,7):"^^^^^^^^^^^^^^^" GOSUB ActiveSkylar CALL MAGNIFY(3) :: CALL SPRITE(#1,128,14,120,200) GOSUB StatusDisplay RETURN //***STILL WORKING ON THIS, NEXT IMPLEMENT WEP$ FOR EACH CHARACTER FOR DISPLAY, StatusDisplay: ANXLV=(50-AXP) DISPLAY AT(9,2):"CLASS:"&ACL$; :: DISPLAY AT(9,19):"LEVEL:"&STR$(ALEV); DISPLAY AT(11,2):"HP:"&STR$(AHP)&"/"&STR$(AMHP); :: DISPLAY AT(11,19):"MP:"&STR$(AMP)&"/"&STR$(AMMP); DISPLAY AT(14,2):"STATUS:"&ASTAT$ :: DISPLAY AT(14,19):"EXP:"&STR$(AXP) DISPLAY AT(16,2):"ARMOR:"&AARM$ :: DISPLAY AT(18,2):"WEAPON:"&AWEP$ DISPLAY AT(20,6):"NEXT LEVEL:"&STR$(ANXLV);" EXP" MidStatus-Keyscan2: GOSUB Keyscan IF K=13 THEN GOTO StatusMenu ELSE GOTO MidStatus-Keyscan2 RETURN /////////////////////////////////////////////////////////////////////////////////// //Really want to eliminate this whole variable-loading section... It is the // //bane of my existence. LOL! Anyway, in the Activexxx subs here, the temporary // //set "A" is loaded with all the players' statistics and information... Each // //party member has one, and it simply loads the Aset with the player's global // //variable data. It works fine... just inefficient and space-consuming // /////////////////////////////////////////////////////////////////////////////////// ActiveBeryl: AMHP=BMHP :: AHP=BHP :: AMMP=BMMP :: AMP=BMP :: ACN$="BERYL" :: ANSP=12 :: ANL=5 :: AMN=BMN :: ACL$=BCL$ :: AXP=BXP AARM$=BARM$ :: AWEP$=BWEP$ :: ASTAT$=BSTAT$ :: ANXLV=(50-BXP) :: ALEV=BLEV RETURN ActiveRepto: AMHP=RMHP :: AHP=RHP :: AMMP=RMMP :: AMP=RMP :: ACN$="REPTOSLICER" :: ANSP=9 :: ANL=11 :: AMN=RMN :: ACL$=RCL$ :: AXP=RXP AARM$=RARM$ :: AWEP$=RWEP$ :: ASTAT$=RSTAT$ :: ANXLV=(50-RXP) :: ALEV=RLEV RETURN ActiveMarkus: AMHP=MMHP :: AHP=MHP :: AMMP=MMMP :: AMP=MMP :: ACN$="MARKUS" :: ANSP=12 :: ANL=6 :: AMN=MMN :: ACL$=MCL$ :: AXP=MXP AARM$=MARM$ :: AWEP$=MWEP$ :: ASTAT$=MSTAT$ :: ANXLV=(50-MXP) :: ALEV=MLEV RETURN ActiveSkylar: AMHP=SMHP :: AHP=SHP :: AMMP=SMMP :: AMP=SMP :: ACN$="SKYLAR" :: ANSP=12 :: ANL=6 :: AMN=SMN :: ACL$=SCL$ :: AXP=SXP AARM$=SARM$ :: AWEP$=SWEP$ :: ASTAT$=SSTAT$ :: ANXLV=(50-SXP) :: ALEV=SLEV RETURN 3 Quote Link to comment https://forums.atariage.com/topic/237458-to-optimize-or-to-scrap/ Share on other sites More sharing options...
+InsaneMultitasker Posted April 20, 2015 Share Posted April 20, 2015 Without trying to understand the code or the flow, my only advice would be to consider using SUBprograms. It seems a lot of your variable swapping and challenges -could- be alleviated by leveraging the subprogram strengths of segregating the global and local data. Quote Link to comment https://forums.atariage.com/topic/237458-to-optimize-or-to-scrap/#findComment-3222661 Share on other sites More sharing options...
+eebuckeye Posted April 20, 2015 Share Posted April 20, 2015 Not much help but this looks great!! Nice job!! 2 Quote Link to comment https://forums.atariage.com/topic/237458-to-optimize-or-to-scrap/#findComment-3222688 Share on other sites More sharing options...
+adamantyr Posted April 20, 2015 Share Posted April 20, 2015 Without trying to understand the code or the flow, my only advice would be to consider using SUBprograms. It seems a lot of your variable swapping and challenges -could- be alleviated by leveraging the subprogram strengths of segregating the global and local data. I agree! Plus, converting your party data and other data into arrays will save you a LOT of repetition. I tried making a start of it with your listing, but you don't have all your data defined... If you can provide a complete listing of all your character variable names and their meaning, we can consolidate them into the appropriate arrays. Quote Link to comment https://forums.atariage.com/topic/237458-to-optimize-or-to-scrap/#findComment-3222724 Share on other sites More sharing options...
Opry99er Posted April 21, 2015 Author Share Posted April 21, 2015 I will be able to post my complete variable listing when I get home. Adamantyr and I had spoken off-board about organization of arrays and how to go about eliminating the need for the VAST majority of temporary sets. When I started working on this block, I started at the top... Main menu, then built all the segments from there--down. A better method would have been to compartmentalize each of the segments prior to coding, then determine what variables would have been needed for each, then come up with a data structure to encompass the needed values into arrays. At the time, I did not KNOW exactly what all I wanted to do, so it was sort of free form and a bit uncalculated. Now I have the outline and the majority of it fully fleshed and functional, but it is still wonky because I started at the top and did one section at a time, repeating alot of things as I went. live and learn. For the primary ITEM menu, for example, rather than jumping to the "Active" subroutine which loads all the player's info into a temp. variable set, it would make a ton more sense to have the variables in Arrays, thereby allowing the keypress of the user to determine the first dimension of the necessary arrays, just by pressing the key! It seems simple now, but Like I said, I did not see the full picture at the time of initial outset. I'll post the entire variable set tonight when I get home. Thanks for the advice and help, guys. Quote Link to comment https://forums.atariage.com/topic/237458-to-optimize-or-to-scrap/#findComment-3222815 Share on other sites More sharing options...
Opry99er Posted April 21, 2015 Author Share Posted April 21, 2015 Okay... I am going to try to lay out my variables as best I can here... While they're all perfectly clear in my head, they don't look quite as simple and pleasant on paper here. ***Numeric, party-member-specific variables: BMHP=20 :: BHP=15 :: BMMP=20 :: BMP=5 :: BDEF=10 :: BATK=10 :: BMDEF=7 :: BMATK=4 :: BXP=10 RMHP=16 :: RHP=5 :: RMMP=40 :: RMP=20 :: RDEF=3 :: RATK=4 :: RMDEF=10 :: RMATK=12 :: RXP=15 MMHP=25 :: MHP=18 :: MMMP=0 :: MMP=0 :: MDEF=15 :: MATK=15 :: MMDEF=5 :: MMATK=0 :: MXP=15 SMHP=12 :: SHP=5 :: SMMP=20 :: SMP=12 :: SDEF=5 :: SATK=4 :: SMDEF=9 :: SMATK=8 :: SXP=0 These are global, spanning the entirety of the game, whether in combat, menu, status... these are the numeric variables which follow the characters all the days of their lives. Each set is specific to the character. Any time you see a "B" prefix to a variable name, it refers to Beryl. Any time you see "R", it is for Reptoslicer, etc etc. MHP=max health points HP=health points MMP=max magic points MP=magic points DEF=defense ATK=attack MDEF=magic defense MATK=magic attack XP=experience points ***Please note that since I have not built the battle engine completely yet, the variables which will be specific to battle are not contained here (except for ATK, DEF, MATK, MDEF) ***String, party-member-specific variables: BARM$="LEATHER" :: BWEP$="DAGGER" :: BSTAT$="HEALTHY" RARM$="WIZARDS ROBE" :: RWEP$="NONE" :: RSTAT$="HEALTHY" MARM$="LEATHER" :: MWEP$="BROADSWORD" :: MSTAT$="HEALTHY" SARM$="SPRITES CAP" :: SWEP$="DAGGER" :: SSTAT$="HEALTHY" BCL$="HERO" :: RCL$="MAGE" :: MCL$="FIGHTER" :: SCL$="THIEF" As on the numeric variables, these are member-specific... B for Beryl, R for Reptoslicer, etc. ARM$=armor name WEP$=weapon name STAT$=current status (HEALTHY, POISONED, FALLEN, etc) CL$=class name (this will change for two of the characters, later in the game) There are likely to be more of these party-member-specific string variables as the game continues to develop, but this is all I needed for now. ***Non-party-member-specific (temporary) variable sets... As you can see in my code, I have a section called "Activexxx" which loads the temporary variable set "A" with the stats of the selected character. Here is a copy of that segment of code... ActiveBeryl: AMHP=BMHP :: AHP=BHP :: AMMP=BMMP :: AMP=BMP :: ACN$="BERYL" :: ANSP=12 :: ANL=5 :: AMN=BMN :: ACL$=BCL$ :: AXP=BXP AARM$=BARM$ :: AWEP$=BWEP$ :: ASTAT$=BSTAT$ :: ANXLV=(50-BXP) :: ALEV=BLEV RETURN ActiveRepto: AMHP=RMHP :: AHP=RHP :: AMMP=RMMP :: AMP=RMP :: ACN$="REPTOSLICER" :: ANSP=9 :: ANL=11 :: AMN=RMN :: ACL$=RCL$ :: AXP=RXP AARM$=RARM$ :: AWEP$=RWEP$ :: ASTAT$=RSTAT$ :: ANXLV=(50-RXP) :: ALEV=RLEV RETURN ActiveMarkus: AMHP=MMHP :: AHP=MHP :: AMMP=MMMP :: AMP=MMP :: ACN$="MARKUS" :: ANSP=12 :: ANL=6 :: AMN=MMN :: ACL$=MCL$ :: AXP=MXP AARM$=MARM$ :: AWEP$=MWEP$ :: ASTAT$=MSTAT$ :: ANXLV=(50-MXP) :: ALEV=MLEV RETURN ActiveSkylar: AMHP=SMHP :: AHP=SHP :: AMMP=SMMP :: AMP=SMP :: ACN$="SKYLAR" :: ANSP=12 :: ANL=6 :: AMN=SMN :: ACL$=SCL$ :: AXP=SXP AARM$=SARM$ :: AWEP$=SWEP$ :: ASTAT$=SSTAT$ :: ANXLV=(50-SXP) :: ALEV=SLEV RETURN As you can see above, it is not a DIRECT copy of the above variables... there are a few new ones. ANSP and ANL stand for: "Name Starting Point" and "Name Length".... Essentially loading these variables into the "A" set allows me to have a uniform "SCREEN INFO DRAW" subroutine, just replacing the name length and name starting point with those specific to the characters. "Reptoslicer" and "Beryl" would not look the same, displayed both starting at (6,5)..... Nor would I be able to do the "underline" of the names I do in the menu display by simply using NSP and NL. The "CN$" variable is simply the character's name and the NXLV numeric variable is simply a value for "Next Level" which you can see on the STATUS menu of the game. I will post a screenshot below so you can see how all these temporary variables are being used. I think I have covered all the variables here, except for the other two temporary sets "C" and "RP" They are just copies of the A set used during the spellcasting menu... In order to be able to simultaneously display character data and then update it upon cast, I needed a way to do quick-loads of character data, then do a fast modify (once spell was cast) and then reload the new RP and C sets back into their respective players' static permanent variable sets. Since the menu calls subroutines from subroutines, once the values are modified, the program simply RETURNs up to the calling sub, the players' static permanent variables are updated, and the program returns to the root of the menu.... Reading the code block I posted at the top of this thread will clearly show what I'm talking about.... even if I'm not making a ton of sense here. Anyway... That's it. You have my entire variable set structure for the game (so far.) ***My plan for doing legit modification to the variables by plugging them into arrays will look something like this: HP(4,2) **4 party members, MHP and HP MP(4,2) **4 party members, MMP and MP XP(4) **4 party members XP BAT(4,2) **4 party members, ATK and DEF MBAT(4,2) **4 party members, MATK and MDEF EQUIP$(4,2) **4 party members, ARM$ and WEP$ STAT$(4) **4 party members STAT$ (status) That's the start of what I'm hoping to do..... I'm certainly open for suggestions... you guys have already given me alot to think about and I appreciate it. Quote Link to comment https://forums.atariage.com/topic/237458-to-optimize-or-to-scrap/#findComment-3222911 Share on other sites More sharing options...
+adamantyr Posted April 21, 2015 Share Posted April 21, 2015 Okay... I am going to try to lay out my variables as best I can here... While they're all perfectly clear in my head, they don't look quite as simple and pleasant on paper here. ***Numeric, party-member-specific variables: BMHP=20 :: BHP=15 :: BMMP=20 :: BMP=5 :: BDEF=10 :: BATK=10 :: BMDEF=7 :: BMATK=4 :: BXP=10 RMHP=16 :: RHP=5 :: RMMP=40 :: RMP=20 :: RDEF=3 :: RATK=4 :: RMDEF=10 :: RMATK=12 :: RXP=15 MMHP=25 :: MHP=18 :: MMMP=0 :: MMP=0 :: MDEF=15 :: MATK=15 :: MMDEF=5 :: MMATK=0 :: MXP=15 SMHP=12 :: SHP=5 :: SMMP=20 :: SMP=12 :: SDEF=5 :: SATK=4 :: SMDEF=9 :: SMATK=8 :: SXP=0 These are global, spanning the entirety of the game, whether in combat, menu, status... these are the numeric variables which follow the characters all the days of their lives. Each set is specific to the character. Any time you see a "B" prefix to a variable name, it refers to Beryl. Any time you see "R", it is for Reptoslicer, etc etc. MHP=max health points HP=health points MMP=max magic points MP=magic points DEF=defense ATK=attack MDEF=magic defense MATK=magic attack XP=experience points ***Please note that since I have not built the battle engine completely yet, the variables which will be specific to battle are not contained here (except for ATK, DEF, MATK, MDEF) ***String, party-member-specific variables: BARM$="LEATHER" :: BWEP$="DAGGER" :: BSTAT$="HEALTHY" RARM$="WIZARDS ROBE" :: RWEP$="NONE" :: RSTAT$="HEALTHY" MARM$="LEATHER" :: MWEP$="BROADSWORD" :: MSTAT$="HEALTHY" SARM$="SPRITES CAP" :: SWEP$="DAGGER" :: SSTAT$="HEALTHY" BCL$="HERO" :: RCL$="MAGE" :: MCL$="FIGHTER" :: SCL$="THIEF" As on the numeric variables, these are member-specific... B for Beryl, R for Reptoslicer, etc. ARM$=armor name WEP$=weapon name STAT$=current status (HEALTHY, POISONED, FALLEN, etc) CL$=class name (this will change for two of the characters, later in the game) There are likely to be more of these party-member-specific string variables as the game continues to develop, but this is all I needed for now. ***Non-party-member-specific (temporary) variable sets... As you can see in my code, I have a section called "Activexxx" which loads the temporary variable set "A" with the stats of the selected character. Here is a copy of that segment of code... ActiveBeryl: AMHP=BMHP :: AHP=BHP :: AMMP=BMMP :: AMP=BMP :: ACN$="BERYL" :: ANSP=12 :: ANL=5 :: AMN=BMN :: ACL$=BCL$ :: AXP=BXP AARM$=BARM$ :: AWEP$=BWEP$ :: ASTAT$=BSTAT$ :: ANXLV=(50-BXP) :: ALEV=BLEV RETURN ActiveRepto: AMHP=RMHP :: AHP=RHP :: AMMP=RMMP :: AMP=RMP :: ACN$="REPTOSLICER" :: ANSP=9 :: ANL=11 :: AMN=RMN :: ACL$=RCL$ :: AXP=RXP AARM$=RARM$ :: AWEP$=RWEP$ :: ASTAT$=RSTAT$ :: ANXLV=(50-RXP) :: ALEV=RLEV RETURN ActiveMarkus: AMHP=MMHP :: AHP=MHP :: AMMP=MMMP :: AMP=MMP :: ACN$="MARKUS" :: ANSP=12 :: ANL=6 :: AMN=MMN :: ACL$=MCL$ :: AXP=MXP AARM$=MARM$ :: AWEP$=MWEP$ :: ASTAT$=MSTAT$ :: ANXLV=(50-MXP) :: ALEV=MLEV RETURN ActiveSkylar: AMHP=SMHP :: AHP=SHP :: AMMP=SMMP :: AMP=SMP :: ACN$="SKYLAR" :: ANSP=12 :: ANL=6 :: AMN=SMN :: ACL$=SCL$ :: AXP=SXP AARM$=SARM$ :: AWEP$=SWEP$ :: ASTAT$=SSTAT$ :: ANXLV=(50-SXP) :: ALEV=SLEV RETURN As you can see above, it is not a DIRECT copy of the above variables... there are a few new ones. ANSP and ANL stand for: "Name Starting Point" and "Name Length".... Essentially loading these variables into the "A" set allows me to have a uniform "SCREEN INFO DRAW" subroutine, just replacing the name length and name starting point with those specific to the characters. "Reptoslicer" and "Beryl" would not look the same, displayed both starting at (6,5)..... Nor would I be able to do the "underline" of the names I do in the menu display by simply using NSP and NL. The "CN$" variable is simply the character's name and the NXLV numeric variable is simply a value for "Next Level" which you can see on the STATUS menu of the game. I will post a screenshot below so you can see how all these temporary variables are being used. I think I have covered all the variables here, except for the other two temporary sets "C" and "RP" They are just copies of the A set used during the spellcasting menu... In order to be able to simultaneously display character data and then update it upon cast, I needed a way to do quick-loads of character data, then do a fast modify (once spell was cast) and then reload the new RP and C sets back into their respective players' static permanent variable sets. Since the menu calls subroutines from subroutines, once the values are modified, the program simply RETURNs up to the calling sub, the players' static permanent variables are updated, and the program returns to the root of the menu.... Reading the code block I posted at the top of this thread will clearly show what I'm talking about.... even if I'm not making a ton of sense here. Anyway... That's it. You have my entire variable set structure for the game (so far.) ***My plan for doing legit modification to the variables by plugging them into arrays will look something like this: HP(4,2) **4 party members, MHP and HP MP(4,2) **4 party members, MMP and MP XP(4) **4 party members XP BAT(4,2) **4 party members, ATK and DEF MBAT(4,2) **4 party members, MATK and MDEF EQUIP$(4,2) **4 party members, ARM$ and WEP$ STAT$(4) **4 party members STAT$ (status) That's the start of what I'm hoping to do..... I'm certainly open for suggestions... you guys have already given me alot to think about and I appreciate it. You may want to do your STATS and EQUIP as numeric variables and keep the names of equipment and stat values in separate static string arrays. That's going to be way faster for comparisons and checks. For example, you'd have STAT(4), with 1 being Healthy, 2 is Poisoned, 3 is Fallen And then STAT$(3) has "HEALTHY", "POISONED", and "FALLEN". So to see your stat value you print STAT$(STAT(P)) where P is the player number (1-4) Quote Link to comment https://forums.atariage.com/topic/237458-to-optimize-or-to-scrap/#findComment-3223087 Share on other sites More sharing options...
Opry99er Posted April 21, 2015 Author Share Posted April 21, 2015 Thanks... I had thought about having both a string and a numeric variable for status... But went with string instead. You are right though... Numeric makes more sense. Quote Link to comment https://forums.atariage.com/topic/237458-to-optimize-or-to-scrap/#findComment-3223104 Share on other sites More sharing options...
Opry99er Posted April 21, 2015 Author Share Posted April 21, 2015 WEP and ARM too then... Quote Link to comment https://forums.atariage.com/topic/237458-to-optimize-or-to-scrap/#findComment-3223105 Share on other sites More sharing options...
Opry99er Posted April 21, 2015 Author Share Posted April 21, 2015 I had planned to use LEN to do comparisons... 6,7, and 8 for FALLEN, HEALTHY, and POISONED, respectively. But numeric variables do make more sense. Quote Link to comment https://forums.atariage.com/topic/237458-to-optimize-or-to-scrap/#findComment-3223134 Share on other sites More sharing options...
+adamantyr Posted April 21, 2015 Share Posted April 21, 2015 (edited) On paper, doing string comparisons SOUNDS better, but believe me, it's going to hurt you come performance time. In particular, string comparisons are literally doing byte-by-byte checks of the two strings, where doing a numeral comparison of two integers will take MUCH less time. I've noticed myself that a big hurdle is that Extended BASIC is not very fast at updating displays... I was made aware of this again when I was writing Space Trek. So you'll want to simplify that as much as possible and make sure you're not doing expensive computations. Edited April 21, 2015 by adamantyr 1 Quote Link to comment https://forums.atariage.com/topic/237458-to-optimize-or-to-scrap/#findComment-3223350 Share on other sites More sharing options...
Opry99er Posted April 22, 2015 Author Share Posted April 22, 2015 Thanks Adam! This is going to be a trip. LOL!!! I foresee insanity in my immediate future. Quote Link to comment https://forums.atariage.com/topic/237458-to-optimize-or-to-scrap/#findComment-3223430 Share on other sites More sharing options...
Opry99er Posted April 22, 2015 Author Share Posted April 22, 2015 (edited) Here's what I've got so far... Getting there...... a little at a time. Arraybuild: DIM HP(4,2),MP(4,2),XP(4),LEV(4),CL$(4),NDIS(4,2) FOR X=1 TO 4 :: FOR Y=1 TO 2 :: READ B :: HP(X,Y)=B :: NEXT Y :: NEXT X FOR X=1 TO 4 :: FOR Y=1 TO 2 :: READ B :: MP(X,Y)=B :: NEXT Y :: NEXT X FOR X=1 TO 4 :: READ B :: XP(X)=B :: NEXT X FOR X=1 TO 4 :: READ B :: LEV(X)=B :: NEXT X FOR X=1 TO 4 :: READ B$ :: CL$(X)=B$ :: NEXT X FOR X=1 TO 4 :: FOR Y=1 TO 2 :: READ B :: NDIS(X,Y)=B :: NEXT Y :: NEXT X . . . . ArrayData: DATA 20,15,16,5,25,18,12,5 DATA 20,5,40,20,0,0,20,12 DATA 10,15,15,0,1,1,1,1 DATA HERO,MAGE,FIGHTER,THIEF DATA 12,5,9,11,12,6,12,6 Edited April 22, 2015 by Opry99er Quote Link to comment https://forums.atariage.com/topic/237458-to-optimize-or-to-scrap/#findComment-3223556 Share on other sites More sharing options...
Opry99er Posted April 22, 2015 Author Share Posted April 22, 2015 Once all the arrays are set, I'll convert all the global variable display stuff with the new array data. This will make life so much easier, and I can basically throw out much of the temporary variable stuff, simplifying the code drastically. Quote Link to comment https://forums.atariage.com/topic/237458-to-optimize-or-to-scrap/#findComment-3223561 Share on other sites More sharing options...
+adamantyr Posted April 22, 2015 Share Posted April 22, 2015 Looks great! One small adjustment; you can READ directly into your array variables, you don't need to read into a temporary one first. Quote Link to comment https://forums.atariage.com/topic/237458-to-optimize-or-to-scrap/#findComment-3223703 Share on other sites More sharing options...
Opry99er Posted April 22, 2015 Author Share Posted April 22, 2015 Yea, I just couldnt get it to work right last night, so I went with something that worked for me in the past. Ill get more done on it tonight... May even get to replace all solo globals. Quote Link to comment https://forums.atariage.com/topic/237458-to-optimize-or-to-scrap/#findComment-3223751 Share on other sites More sharing options...
+InsaneMultitasker Posted April 22, 2015 Share Posted April 22, 2015 I foresee insanity in my immediate future. Nothing wrong with that! Quote Link to comment https://forums.atariage.com/topic/237458-to-optimize-or-to-scrap/#findComment-3223786 Share on other sites More sharing options...
Opry99er Posted April 22, 2015 Author Share Posted April 22, 2015 ^^true that......^^ Quote Link to comment https://forums.atariage.com/topic/237458-to-optimize-or-to-scrap/#findComment-3223843 Share on other sites More sharing options...
JamesD Posted April 22, 2015 Share Posted April 22, 2015 Here's what I've got so far... Getting there...... a little at a time. Arraybuild: DIM HP(4,2),MP(4,2),XP(4),LEV(4),CL$(4),NDIS(4,2) FOR X=1 TO 4 :: FOR Y=1 TO 2 :: READ B :: HP(X,Y)=B :: NEXT Y :: NEXT X FOR X=1 TO 4 :: FOR Y=1 TO 2 :: READ B :: MP(X,Y)=B :: NEXT Y :: NEXT X FOR X=1 TO 4 :: READ B :: XP(X)=B :: NEXT X FOR X=1 TO 4 :: READ B :: LEV(X)=B :: NEXT X FOR X=1 TO 4 :: READ B$ :: CL$(X)=B$ :: NEXT X FOR X=1 TO 4 :: FOR Y=1 TO 2 :: READ B :: NDIS(X,Y)=B :: NEXT Y :: NEXT X . . . . ArrayData: DATA 20,15,16,5,25,18,12,5 DATA 20,5,40,20,0,0,20,12 DATA 10,15,15,0,1,1,1,1 DATA HERO,MAGE,FIGHTER,THIEF DATA 12,5,9,11,12,6,12,6 You can speed that up by interleaving the data and reducing the number of separate loops. Quote Link to comment https://forums.atariage.com/topic/237458-to-optimize-or-to-scrap/#findComment-3223953 Share on other sites More sharing options...
Opry99er Posted April 22, 2015 Author Share Posted April 22, 2015 Yea... I'm trying it, but I.am terrible at that kind of stuff. LOL! I'll have a couple hours tonight where I'm hoping to knock this whole thing out and then find out how much PROGRAM space I've saved. Quote Link to comment https://forums.atariage.com/topic/237458-to-optimize-or-to-scrap/#findComment-3223966 Share on other sites More sharing options...
+adamantyr Posted April 22, 2015 Share Posted April 22, 2015 Here you are: Arraybuild: DIM HP(4,2),MP(4,2),XP(4),LEV(4),CL$(4),NDIS(4,2) FOR X=1 TO 4 :: FOR Y=1 TO 2 :: READ HP(X,Y),MP(X,Y),NDIS(X,Y):: NEXT Y :: NEXT X FOR X=1 TO 4 :: READ XP(X),LEV(X),CL$(X):: NEXT X ArrayData: DATA 20,20,12,15,5,5,16,40,9,5,20,11 DATA 25,0,12,18,0,6,12,20,12,5,12,6 DATA 10,1,HERO DATA 15,1,MAGE DATA 15,1,FIGHTER DATA 0,1,THIEF Quote Link to comment https://forums.atariage.com/topic/237458-to-optimize-or-to-scrap/#findComment-3223991 Share on other sites More sharing options...
Opry99er Posted April 22, 2015 Author Share Posted April 22, 2015 That is just stupid.... Quote Link to comment https://forums.atariage.com/topic/237458-to-optimize-or-to-scrap/#findComment-3223994 Share on other sites More sharing options...
Opry99er Posted April 23, 2015 Author Share Posted April 23, 2015 So all 2D arrays can be fed in the first line, all 1D arrays can be done in the second... I have more arrays... Just haven't done them yet. Freakin awesome... Learn something new EVERY DAY. Much appreciated. 2 Quote Link to comment https://forums.atariage.com/topic/237458-to-optimize-or-to-scrap/#findComment-3224012 Share on other sites More sharing options...
JamesD Posted April 23, 2015 Share Posted April 23, 2015 Terribly difficult isn't it? Quote Link to comment https://forums.atariage.com/topic/237458-to-optimize-or-to-scrap/#findComment-3224104 Share on other sites More sharing options...
Opry99er Posted April 23, 2015 Author Share Posted April 23, 2015 Just a head game... I have never done much with READ and DATA, so it is new to me. Honestly, other than some disk-file population tests I did a few years ago, I have never used them in a program of mine. Quote Link to comment https://forums.atariage.com/topic/237458-to-optimize-or-to-scrap/#findComment-3224105 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.