Jump to content

Creating More Space In The SCM File


demonj0e

Recommended Posts

right the limit is realy pissing me off cuz its so eaily reached so dose anyone know ways to create more space in the scm?

 

i know that deleting the help thread and code can make room but is there anything else?

Link to comment
Share on other sites

When I want to add space for weapons, I usually deleted all of the flower pickups. I think they're useless.
Link to comment
Share on other sites

ok ty ill get rid o sum of them usless pickups see if that makes a difference

 

btw if the definaed memory is lower than i needs to be dos that stop the external scripts form working?

Link to comment
Share on other sites

btw if the definaed memory is lower than i needs to be dos that stop the external scripts form working?

Defined memory can never be lower than it needs to be. The Builder won't even compile it.

 

@Everybody: I've worked with dem0n quite a bit in private. He claims to understand some things, but presses on as if he does not. He's a bit too eager for results and not willing to invest the time to properly achieve them. Just yesterday, he asked me this very question in private. When I explained that how to write code more efficiently isn't something you can really teach, but rather something you pick up in time as you gain more experience, he claimed to understand that. confused.gif For him to ask it here, he's just jerking you guys around.

 

@dem0n: Unless your code is meant to be compatible with existing savegames, there's no reason you can't develop your work in a stripped SCM where you have all the space in the world. Oh wait, I"ve already explained this to you several times to which you've replied "ok" each time. Nevermind then sarcasm.gif

Link to comment
Share on other sites

1. Delete parts from the main segment: I deleted parts that were never run. You can easily find these parts by using find for the "jump" opcode, and delete all code after that until the next label. Don't bother after you hit mission 0, it won't affect the script limits.

 

2. Replace commonly used code with subroutines: Places where the code checks to see if player is defined, if fading, etc can be replaced with gosubs:

 

:SomeLabelwait 0if 0is_player_definedjf LLSomeLabelfade 0 500:SomeLabel2if 0fading jf LLSomeLabel3wait 0jump LLSomeLabel2:SomeLabel3

 

can become

 

 

:SomeLabelwait 0gosub LLGLOBALSUBifdeffade 0 500gosub LLGLOBALSUBfadechk...:GLOBALSUBifdefwait 0if 0is_player_definedjf LLGLOBALSUBifdefreturn:GLOBALSUBfadechkwait 0if 0NOT fading jf LLGLOBALSUBfadechkreturn

 

This wouldn't save much space in the above example, but if used on every check in the main segment, will save a lot of space. Optimally, you could use a program to detect code like this and utilize this method, but none has been written AFAIK.

 

cough..programmersreadingpleasenotce..cough

 

3. Farm out parts of your code to missions. SA has 135 by default, and it supports 170. Only downside to this is not being able to use that part of your mod while on an actual mission in game.

 

4. Optimize your mod: Less globals mean less space in main segment. Replace as many of them as possible with locals. Also, read over your code and find anything that would save space as a subroutine. Most code copied from Rockstar, then edited, is very bloated. You can usually trim down these codes substantially.

Link to comment
Share on other sites

VERY rarely do you want an if player defined check to go back to the label that used it. In the very beginning of many script mods, but usually just that once. And I don't think R* did it once in original code. I was surprised that they did NOT do the fading since they did in VC.

 

Also, I would not recommend using missions to coders that aren't very far along since there are at least a few IMPORTANT differences about them.

Link to comment
Share on other sites

@Everybody: I've worked with dem0n quite a bit in private. He claims to understand some things, but presses on as if he does not. He's a bit too eager for results and not willing to invest the time to properly achieve them. Just yesterday, he asked me this very question in private. When I explained that how to write code more efficiently isn't something you can really teach, but rather something you pick up in time as you gain more experience, he claimed to understand that. confused.gif For him to ask it here, he's just jerking you guys around.

 

@dem0n: Unless your code is meant to be compatible with existing savegames, there's no reason you can't develop your work in a stripped SCM where you have all the space in the world. Oh wait, I"ve already explained this to you several times to which you've replied "ok" each time. Nevermind then sarcasm.gif[/color]

thankyou all for help and demareast im asking ways to save space in a scm to find out what is not needed, i didnt say anything like "oh tell me ways to save space in a scm cuz i cant be botherd to put my mod in a stipped one"

 

and about the defined memory, My defined memory at the min is 45200

and it compiles but says

 

Memory beyond the defined range has been acsessed use

DEFINE MEMORY 46007

or higher to allocate enough memory

 

and then it says its compiled and my game runs but i think its causing some things not to run eg the scripts and if i make it any higher it goes past the limit making the size 200,743

Link to comment
Share on other sites

You're adding way too many globals. That's what defined memory is for and increasing WILL increase the overall size of your MAIN. Ever since just under 2 years ago when I learned about local vars, I've said "use locals instead of globals when possible" EVERY time I've seen posted code that used globals unnecessarily. Even if you missed all of them, I've said it to you specifically at least half a dozen times. By my calculations, you're adding 552 globals to original code. That HAS to be mulitple mods and for each mod, you can convert 32 of them to locals each.
Link to comment
Share on other sites

Yes, but 32 and 33 are internal timers. You won't find globals with that role. That's why I said 32: 0 - 31.
Link to comment
Share on other sites

In the decompiled code, the variable names are a reference to their original DMA address, and are re-compiled to that.

 

If you have deleted some, re-name all the rest (eg do a global replace and change al the '$'s to '$my') so they are no longer DMA, they will be allocated space on the fly, e.g. the first available address. If in a stripped script, you have 3 variables, and call one $9999, you will need to define memory as 39996 (9999 * 4) as although you will only need maybe 20 bytes, the mission builder converts 9999 to its hex memory allocation equivalent (9C3C) so it needs that address within the defined memory space.

 

If you add 'my' to all the names, they will no longer be DMA and will be assigned addresses, so that should reduce memory usage if you have deleted any (also look for definitions of variables which you have replaced wth locals as they may be defined outside the thread so will still be stealing memory).

Link to comment
Share on other sites

That won't help him. If he's made to redefine to a greater number, he's already filled all the holes left by original code.

 

I also wanted to point out that anybody that intentionally kills DMA in their script will also be killing any Darkpact compatibility potential.

Link to comment
Share on other sites

Hi

It's might be the wrong topic but i havn't understand some things you said

 

@y-less: are you saying that if i put $myvariable it's not counted in the define memory but $variable is ?????? and if i read right then, you are talk about globals not locals ??

 

@dreamrest: Are you telling that @localvariables are limited to @32, or maybe you are saying that only the first thirty are usable in the first main part (or stripped scm) ???

coz i've seen @56, @168,..... in the missions and external script parts, and i thought they were forbiddens (@locals) in the main part.

 

@anyone: by the way just a little question for a piece of code (a script that isn't one yet...) that must run any moment in the game: like petrol on car or that cj need to piss or anything that need to be running all the time, well that piece of code should be an external script or piece of code in the main part with thousands and thousands of globals which is gonna waste a the memory allocation and get to 50 000 (back then i thought that 46 000 was a lot!!!!)

 

HAve fun people

 

Link to comment
Share on other sites

@y-less: are you saying that if i put $myvariable it's not counted in the define memory  but $variable is ?????? and if i read right then, you are talk about globals not locals ??
No. I'll try to explain it, though it's a little advanced. He was referring to variables that look like $218. Numerical $ vars are DMA (direct memory access). That means that $218 resides in the 218th slot for global vars, which are all staked out in the beginning by define memory. During development, R* might end up not using some of those for whatever reason. This leaves holes in the define memory area. When MB comiples code, it will take a non-DMA global and file it into the first hole it finds. If you change the names of variables from DMA to non-DMA ($218 to $my218), the Builder will no longer file ANY vars into specific places and will automatically squish them all together in the beginning.

 

I later pointed out that there is a flaw in this theory. The original define memory is obviously going to be larger or as large as the largest DMA global. You wouldn't need up the amount until you used so many globals that MB filled all the holes and needed more space to fit them into. If all the holes are filled, then taking away the DMA status of globals won't make the lot of them together any smaller. And with Darkpact as well as other developments that take advantage of DMA emerge, it's important for coders to preserve that as much as possible to make their work as compatible as possible. That's WHY I pointed out that in this case it wouldn't help, to deter anybody who would use it for that reason to needlessly de-compatible-ize their work.

 

 

@dreamrest: Are you telling that @localvariables are limited to @32, or maybe you are saying that only the first thirty are usable in the first main part (or stripped scm) ???

coz i've seen @56, @168,..... in the missions and external script parts, and i thought they were forbiddens (@locals) in the main part.

ANY thread may use locals. Threads in the MAIN section are limited to @0 through @31 as well as @32 and @33 which can only be used as internal timers. Mission threads can have as many as 1024 total local vars. That's why you've seen locals >32. According to original code, external threads follow the rules of mission threads in terms of local variable use.

 

 

@anyone: by the way just a little question for a piece of code (a script that isn't one yet...) that must run any moment in the game: like petrol on car or that cj need to piss or anything that need to be running all the time, well that piece of code should be an external script or piece of code in the main part with thousands and thousands of globals which is gonna waste a the memory allocation and get to 50 000 (back then i thought that 46 000 was a lot!!!!)
Without specifics, nobody could answer this question. As a general rule, any code that runs all the time belongs in MAIN. With SA's limitations so constrictive, the desire to farm things out to externals is obvious. However, the fact that external threads are NOT automatically started on a game load, nor are any of their variables should discourage most potential apllications of external threads. External threads have very specific roles and are generally tied to object. For example, even though there are 4 places to use a weight bench, there is only one external thread. It's for code that is NOT used all the time, but may be used repeatedly. It's almost like a gosub for an entire "mod". But instead of having a thread always running waiting to see when to gosub, you tie an external to an object and let the engine track it.
Link to comment
Share on other sites

hi

First thanks for the fast answer, i love when people answer right away

 

But i'm sorry i didn't get it all really particulary the DMA and darkpact part (but i'll have to search by myself for better understanding),but you've clearly answered my questions (thanx), and i know now that i can use locals in the main part up to @31 (i don't know yet what's a internal timer, and i've already have to learn more about the inaccurate_float_timers, so i promise i won't be using after @31......smile.gif), that's pretty cool it'll make some memory saving, because using a whole global variable for a variable that the code don't even use is a bit of a waste.

For external script, usually i relly don't like when people are reading my mind !!!!

I mean it's private, don't get into people brain before being invited !!!! smile.gif,

your answer is pretty close to what i thought but you've confirmed it and explained it, and that making the difference.

 

Thanks again and again

 

Don't forget to have fun !!!!!!!!!!!!

 

 

 

Link to comment
Share on other sites

First thanks for the fast answer, i love when people answer right away
Well that's all by chance. I am pretty involved though wink.gif

 

 

But i'm sorry i didn't get it all really particulary the DMA and darkpact part (but i'll have to search by myself for better understanding)
I disagree. I wouldn't have invested the time above if I wasn't interested in helping you to understand. This thread was satisfied before it was created, so for it to sway to one aspect of it for better clarity, there's nothing wrong with that. Darkpact is just an advanced way to get around the savegame incompatibility that used to plague us. You may have heard that when you edit the code, you have to start a new game. Well Darkpact focuses on WHY that is and provides an opportunity to work around it. DMA is also a bit of an advanced concept. In fact, unless you are focusing on savegame compatibility (or other style-breaking techniques like Y_Less arrays), there's NOTHING to gain by putting specific variables into specific slots. That's why I was kind of disappointed that it was even brought up (the renaming of variables), especially since it doesn't really apply to this thread. So you can disregard it if that's easier for you. If you're still confused, feel free to ask. Just know that the Builder readme covers this and a lot more you'll want to be up on.

 

 

(i don't know yet what's a internal timer
Then allow me to explain because these things are too cool to ignore. Let's say you're writing a mod that you want event B to take place 10 seconds after event A. You could just say
event Await 10000event B

But what if you wanted the code to be doing other things in the meantime? How would you go about knowing that 10 seconds have passed? THIS is where thread timers (@32 and @33 for SA, 16@ and 17@ for GTA3/VC) come in. After event A, set one of them to equal 0

0005: @32 =  0

Now each time this thread encounters a wait command, your thread timer will be incremented accordingly. That is to say that unlike other locals, these do NOT stay what you set them at, but rather they grow as they collect the amount of milliseconds that have passed. So in our event A / B example, you just have your code check wherever you'd want it to

00D6: if  0001B:    10000 > @32 ;; integer values004D: jump_if_false ££eventBsLabel

Doing that, your code will continue on while 10000 is greater than your timer's value. Once 10 seconds have elapsed from when you set @32 to 0 though, it will return false, jf to event B's code and you've accomplish your goal. If you'd like a useful example of when such a thing would be useful, you can check out either of my Ancestral Recall Code Tools. It's meant to check your save game for what all you have left to do to reach 100% and put it on screen, one event every 2 seconds. Originally, I told it to put the message up, wait 2 seconds, and then proceed so that the next message it was going to put up wouldn't cause the first to get cut off. But say you're close to having everything done? It takes times to crunch all that data. Switching to an if greater than check with the timers though, I accomplish the crunching WHILE it's waiting, not afterwards. So let's say you have only two things left to do. The old approach would display something, crunch all the data and by time it encountered the next thing, your screen's text had already gone away. That makes it look blinky and makes it harder to read. So instead, whenever I tell it to display something, I set one of the thread timers to 0. Then it continues crunching and if it finds another thing to display, it waits until the thread timer is greater than 2000 (2 seconds), displays the next item, resets the timer to 0, repeata.

 

 

i've already have to learn more about the inaccurate_float_timers
Well you be sure to teach me then. I've only seen them in VC in regards to the first ladder of G-Spotlight. I was never able to re-use them in either Timetwister or Time Vault, but I WAS able to accomplish the same task without them. In other words, I've never had a need to understand them.

 

 

using a whole global variable for a variable that the code don't even use is a bit of a waste.
On that same note, reusing variables will also save space. I run into this all the time as I try to keep all variables a thread uses to just locals. When I was writing Nitz Kit, I used 0@ as a generic dump var. I didn't need Z axis data through most of it, but there are a few opcodes that will only collect X, Y, AND Z at the same time. So I'd make each Z collecting go into my generic dump var just so it had the var it needed and I didn't have to keep giving it new ones. Likewise, that mod had 2 features, warping and spawning cars. Earlier developmental versions saw me using vars 12@ - 14@ for car IDs during the spawning and immediately removing references to them while the warping part used them for XYZ data. Since both sections were done with the vars as soon as they used them, it was okay that they overlapped.

 

 

For external script, usually i relly don't like when people are reading my mind !!!!

I mean it's private, don't get into people brain before being invited !!!! smile.gif

wow.gif Sometimes people complain about the thoroughness of my answers, but I just try to make sure you're up on exactly what you're looking at colgate.gif
Link to comment
Share on other sites

 

Even if you find it normal, thank again for the speedy answer

 

And have a nice week-end, people are waiting for me.

 

PS: so with darkpact i might no to have to start a new game !!!!!!!

(that's crazy), the internal timer @32 and @33 is great sh*t(thank bothering explaining), the inacurate float timer seems to be more complicated than internal but it doesn't seem to be hard, and now i've got to find and replace so many $var to @var, and using duimp var that will save so many memory.... i really got to go

love u for all that bye

 

and never forget Have fun

 

Link to comment
Share on other sites

never forget

Word cool.gif

 

Just got done with a pair of posts that are right in line with this topic's aim, so I thought I'd link them here and throw in another little trick. First, the links: sphere inclusion and conditional lumping. Now for the SMALL trick. I'm going to use tomworld10's location sniffer as an example.

:CHIOTTES_100D6: if  2500FF:   actor $3  0 ()near_point_on_foot 2238.0   -1068.0   1049.0 radius  1.0  1.0  1.000FF:   actor $3  0 ()near_point_on_foot 2279.0   -1139.0   1050.0 radius  1.0  1.0  1.000FF:   actor $3  0 ()near_point_on_foot 2193.0   -1223.0   1049.0 radius  1.0  1.0  1.000FF:   actor $3  0 ()near_point_on_foot 2344.0   -1062.0   1049.0 radius  1.0  1.0  1.000FF:   actor $3  0 ()near_point_on_foot 2254.0   -1217.0   1049.0 radius  1.0  1.0  1.000FF:   actor $3  0 ()near_point_on_foot 2321.0   -1005.0   1054.0 radius  1.0  1.0  1.0004D: jump_if_false ��TEXT_20002: jump ��FEELBETTERNOW_1:TEXT_2

(for the sake of my point, let's pretend that the next section of code is in fact :TEXT_2 as shown) As you can see, if we could make our jf point to someplace else, we could save the need to have a jump there at all and just let the code continue onward. Well you can. You just have to make EACH of the conditionals its own inverse. Changing the first character in an opcode from a 0 to an 8 makes it a NOT. In MB, we see the word NOT appear like so

80FF:   NOT   actor $3  0 ()near_point_on_foot 2238.0   -1068.0   1049.0 radius  1.0  1.0  1.0

If one of your conditionals already is a NOT then you negate it by removing the NOT and changing the first character from an 8 to a 0.

 

BUT, negating all the conditionals and switching the addresses around is not enough. AND will return false if any one of its conditionals are false. Whereas OR will return true if any one of its conditionals are true. So if you negate every conditional you MUST also switch your argument from AND to OR or from OR to AND. The revised code would like like so

:CHIOTTES_100D6: if  580FF:   NOT   actor $3  0 ()near_point_on_foot 2238.0   -1068.0   1049.0 radius  1.0  1.0  1.080FF:   NOT   actor $3  0 ()near_point_on_foot 2279.0   -1139.0   1050.0 radius  1.0  1.0  1.080FF:   NOT   actor $3  0 ()near_point_on_foot 2193.0   -1223.0   1049.0 radius  1.0  1.0  1.080FF:   NOT   actor $3  0 ()near_point_on_foot 2344.0   -1062.0   1049.0 radius  1.0  1.0  1.080FF:   NOT   actor $3  0 ()near_point_on_foot 2254.0   -1217.0   1049.0 radius  1.0  1.0  1.080FF:   NOT   actor $3  0 ()near_point_on_foot 2321.0   -1005.0   1054.0 radius  1.0  1.0  1.0004D: jump_if_false ��FEELBETTERNOW_10002: jump ��TEXT_2:TEXT_2

We switched the argument from OR to AND, negated each conditional, and exchanged the target address of true and false. Now that we've arranged it so that the 0002 jump command points to the very next line, we can get rid of it and free up 7 bytes.

 

7 bytes! I read through all that for a measely 7 bytes? NO!!! Almost EVERY single time R* checks to see if models are loaded, they'll use

:INTRO1_12800D6: if  086B9:   NOT   cutscene_data_loaded004D: jump_if_false �INTRO1_1330001: wait  0 ms0002: jump �INTRO1_128:INTRO1_133

...instead of

:INTRO1_1280001: wait  0 ms00D6: if  006B9:   cutscene_data_loaded004D: jump_if_false �INTRO1_128:INTRO1_133

This is R*! Why would they do it that way if it's "wrong"? Well in all fairness, it's NOT wrong. The way they did it means they only run the wait (which IS a necessary evil because it forces the thread to give up control and in the case of loading things, this forfeiture may be unnecessary) if they absolutely have to. But since the name of the game in this thread is trimming down MAIN, this little switcheroo will free up 7 bytes per instance.

 

Edited to remove a paragraph at the end that was misinforming.

Edited by Demarest
Link to comment
Share on other sites

so your sayign dem that changing things like that throughout the scm can save up a fair bit of space? if anyone is crazy enough to spend a day doing that
Link to comment
Share on other sites

Oh, I'm sorry. I thought YOU asked how to save space sigh.gif Ingrateful as always. If you were actually interested in becoming a good coder instead of just achieving results, you'd understand that this isn't JUST about existing code. It's techniques you can pick up to make your own code slimmer. Why, the very thread that example came from was written in a way that observing that technique shaves off 21 bytes for him. What you asked for would require somebody to "be crazy enough to spend a day doing". BUT let's say you did and released the source for it saying "This is the original code slimmed down to help avoid the MAIN limit. It requires you to start a new game, but most mods do anyways. Enjoy." and you'd be a hero. The pioneers are who they are because they fronted the effort so that everybody else doesn't have to.

user posted image

Link to comment
Share on other sites

he he like the pic i think i should listen to him

ok hmmm... i think i might try making a slimmed down scm, ill try a few things usuign the example youve made to see how much space it makes with that then ill try dig up a backup scm and make a full slimmed one

might take about 2-3 weeks id never spend a whole day at my comp

Link to comment
Share on other sites

Hi

@Demonj0e: it didn't took taht long at all !!!!! Maybe like 2 to 3 hours (yeah it's still a while but anyway... biggrin.gif ). I'm crazy enough coz all the room i'd free while be more fun creating little script and would let me to keep my script not too short (I mean not having to take all the littl function of because it takes to much room). And there was something that's actually a good piece of fun (at least for me) is that after doing that you'll have to test it, well just playing and after all this work on the main you really aprceiate playing (and for once for more than 10 minutes!!!).

 

Well I've done it !!!!, the "load cut scene" thing was done all the way to the end (wich freed up like 100 bytes or some in the four first segments) and the conditional lumping was much more lucrativ (much more work as well...) I've only done the main part (I stopped at --------mission 0----------) and it freed up around 5000 (i told you LUCRATIV !!!!), 5ks !!!!!, 5 youpii !!!!!!!!!!! (only on the first four segment....). I've tested it first i used to get a debt phone call straight after getting off the bmx of the beging but that's been fixed and then as far as I've gone I didn't get any trouble or game crashing.

 

user posted image

 

There it is : DOWNLOAD SLIMMED MAIN.SCM HERE

 

@Demarest: Youpiii I'm a Hero cool.gif I'm a pioneer cause i've fronted the effort !!!!

tounge.gifwink.giflol.giflol.giflol.giflol.gif . Hey, wasn't that hard !!!!!!!!!!!!!!!

 

 

Have fun

Link to comment
Share on other sites

no no lol ive done all that allready and more i will start on a slimmed scm now

theres alot more ways to save space just that what dem said about the cuscnene things wich dont take very long atall

 

EDIT: done some more work ive got the space down to 187,505

Edited by demonj0e
Link to comment
Share on other sites

You guys are insane and should just use an optimizing compiler instead of doing all this manual work. Point's first-4-segments are 179,184 as of right now. Writing hand optimized assembly makes sense for small pieces of code, but automated methods really are better for large scale optimization work.

Link to comment
Share on other sites

I agree with you. The difference being that code compiled with their source is not proprietary and any tool can decompile it.
Link to comment
Share on other sites

In this application, it's not literal. Unless I'm mistaken, current decompilers are looking for code in a format that Point's optimization actually modifies in ways that the game may be able to run it, but decompilers can't touch it.
Link to comment
Share on other sites

Eh? If the game can run it, but other tools can't read it, that would mean the "other tools" are buggy. If those tools were fixed, there is no reason they couldn't disassemble the file. (Point's disassembler can read the files perfectly. SADisAsm has a bug with a label and MB gives up with an array type mismatch error.) "Proprietary" makes it sound like Point outputs some format noone else knows, which isn't the case: it generates the same SCM format any other tool would, just more intelligently than existing tools (including R*'s compiler).

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • 1 User Currently Viewing
    0 members, 0 Anonymous, 1 Guest

×
×
  • Create New...

Important Information

By using GTAForums.com, you agree to our Terms of Use and Privacy Policy.