Some Basic Scripts for 4RPL

Started by Corpserule, February 12, 2021, 09:26:43 AM

Previous topic - Next topic

Corpserule

I just finished my map "SmartStash", and inside it, I included several 4RPL scripts, adding commentary on a lot of it. I think it would help anyone who wanted to use 4RPL and doesn't know how to start.

It's by no means an expert's guide, and perhaps i've made a few mistakes (in comments), but i know this would have helped me greatly when I started, so I thought i'd post it here.

I hope this helps any aspiring 4RPL map makers, and god help anyone who actually tries to "win" my map :)

Corpserule

#1
After many hours of thinking it over, my brain finally figured out the obvious reason why the smartstash sometimes makes a tiny bit of anticreeper. (div10 instead of div9 is I was thinking when i was coding it)

Just pre-empting the "im bad at math" jokes.

Well, probably not going to fix it, since i dont want another copy of my map floating around, and it's a very rare occurance regardless

Karsten75

There does not seem to be any code attached to this.

I have a page on the wiki where I am hoping contributors will add code samples and useful snippets.

https://knucklecracker.com/wiki/doku.php?id=cw4:4rpl_tools

Corpserule

#3
I'll add some stuff there today or so.

You can find my map by name in CW4, the idea was to have an example of several functioning scripts of various types and several logics, used together to accomplish a goal.

If the map itself has no scripts attached, i'd find it bizarre as it doesn't behave like that on my end. In which case, sorry. (checked online)

Since this post was intended to show off scripts to new 4RPL coders. I should say that  you can view the code of any map online, by pressing SHIFT+E (causing editor to appear in the bottom right). Then going to Mods->Open CPack->Scripts

An example of something that's difficult to perceive in code is the ADA Logs, which rely on external texts from the editor to function.

The CW4 reference is great for functions once you have built up an understanding of how 4RPL is interacting with the world. but it's difficult to get to the point where you have enough understanding to use them

Corpserule

#4
Reading the utilities, the only thing i've done that's kinda "not in the wiki". Is come up with a combination of code that allows searching for units that do not get picked up by getUnitsInRange

I.E getting around this warning attached to it

:!: Note: Due to some technicalities units which do not occupy any space will never be detected by this command. Whether a custom unit occupies space can be controlled through the CMOD Settings: Settings > Basic > "occupies land"

Tell me if you'd like me to write that as a snippet. Otherwise, the rest was merely using the wiki functions as intended to make a complex interaction happen. (which was making a stash get larger as the game time progressed, while tiptoeing around the max creeper height).


Or I could write an additional tutorial, as i felt like that was where the CW4 reference is most lacking. (I feel the existing tutorials jump from very basic to hyper specific, and lacked the typical actions a map maker would most likely want to use when making a map)

Which would probably be titled
"Creating and modifying existing units through scripts"

Which would also feature basic logic commands (like if statements), other selection methods (other tutorials either rely on GetSelectedUnits, or assume you're making a custom unit), and timers.

321k

#5
Don't know if it's the right place for snippets: Here's a little one to make concatting text easier. For people who are tired typing lines like:
self Text:" <-var1 ", text2: " <-var2 concat4 LF "text3: " <-var3 concat4 SetUnitDebugText

For Debug purposes it's shorter to type:
@sd("Text:" <-var1 ", Text2: " <-var2 LF "Text3: " <-var3)

Here the 2 necessary funcs:
:Cs # concats all elements on stack by space
->cs
while StackSize gt0 repeat
" " <-cs concat3 ->cs
endwhile
<-cs

:Sd # SetUnitDebugText, all args concatted with spaces
@Cs self swap SetUnitDebugText


Be aware that the concattening function @cs consumes the whole stack. Normally your stack should be clean, so no problem. Advantage: if your stack was not clean, you immediatly see it and can investigate the issue.





321k

tl;dr: 2 Functions to concat larger amounts of texts and data with delimiter

The ConcatStack functions have short names for easy scripting. @Cs consumes (like List) whole stack. @CsN works like ListN, so it just concats as many items from stack as you define in command. Additionally the functions have a delimiter parameter, which is inserted between the arguments. The source below could be run in 4rpl console and holds detailled explanations and examples.

"A" "BC "DE" 99 LF "NextLine" @Cs("-") trace  # result: A-BC-DE-99 <linefeed> NextLine


:Once
"xyz" "abc" -1 "A" "B" "C" 99 # arguments on stack
@CsN(4 "-") trace # concats the 4 top stack elements with delimiter "-"
# console log result:
# A-B-C-99

# "xyz" "abc" -1    are still on stack!
@Cs(" ") trace # concats all stack elements with Spaces
# console log result:
# xyz abc -1

@Cs("Use @Cs" "Only When You Know Your" "Stack" " ") trace
@CsN("Concats" "by" "Linefeeds" 3 LF) trace


:Cs # <arg1> ... <argN> <delimiter>
# concat stack, consumes whole stack. last argument must be delimiter
->delim 
while StackSize > (1) repeat
<-delim swap concat3
endwhile

:CsN # <arg1> ... <argN> <numOfArgs> <delimiter>
# concats <numOfArgs> stack items.
->delim 
StackSize swap - ->j
while StackSize <-j gt repeat
<-delim swap concat3
endwhile


The Apocalyptic

I know this is a Necro-post, but perhaps there should be a snippet for setting Packet Request Rates at different values than the default of 1 per 15 frames, or 2/second.

Incidentally, this would help me for my fix of my custom level, so the custom objective is faster. I don't want to do it by reducing the packet requirement, so the only other way would be increasing packet request rates.

Karsten75

Quote from: The Apocalyptic on May 17, 2022, 04:39:18 PM
I know this is a Necro-post, but perhaps there should be a snippet for setting Packet Request Rates at different values than the default of 1 per 15 frames, or 2/second.

Incidentally, this would help me for my fix of my custom level, so the custom objective is faster. I don't want to do it by reducing the packet requirement, so the only other way would be increasing packet request rates.


$rate:15     # A packet every this many frames

:awake
Once
SetUnitPacketRequestRate(self <-rate)
endOnce