PGM
PGM copied to clipboard
Variables match module proposal
This is something that pgm has lacked for long, essentially arbitrary variables that can be set and modified/kept track of, they should allow for more complex gamemodes to be made easier, often hidden hills are used for a "boolean bit" that can be set by a player or similar, this is however far from ideal.
There are many things that are intentionally overlooked for simplicity on this first proposal, the idea is for this to be expanded & modified based on comments and ideas from others.
Initial syntax proposal example:
<variables>
<var id="progress" scope="match" initial-value="0"/>
<var id="team-score" scope="team" initial-value="0"/>
<!-- if the variable should be kept if they rejoin. always, same-team, never -->
<var id="player-score" scope="player" initial-value="0" persist="always"/>
<var id="temp" scope="match" initial-value="0"/>
</variables>
<filters>
<!-- Maybe a better spawn unlocks after a team gets 1000 score? -->
<variable id="unlock-spawn" var="team-score" range="[1000, oo)" />
</filter>
<kits>
<kit id="award-progress">
<!-- Add 5 to the overall match progress -->
<let var="progress" operation="add" amount="5"/>
<!-- Calculate a random value between 20 and 100 -->
<let var="temp" operation="random" amount="80"/>
<let var="temp" operation="add" amount="20"/>
<!-- Add up the progress for both player & team -->
<let var="team-score" operation="add" amount="temp"/>
<let var="player-score" operation="add" amount="temp"/>
</kit>
</kits>
This would make it so the map has 3 main variables, one that is the same for everyone for overall progress, one for team progress, and one for player progress.
The variables can be modified by using kits, which i think is the best "framework" that PGM has to make actions happen (when filters activate, or when you enter a region), although admiteddly currently PGM has no dynamic filters so dynamic kits don't quite give us as much flexibility as that will give us.
You can use these variables in as many filters as you want, maybe enabling faster (or slower) spawns, giving different kits to players that progress, or whatever else. It would also be interesting to allow other places in the codebase to take variables as parameters, so you could for example make respawn time directly dependant on a variable, as this current approach would require you to setup as many respawns as you possibly want, each with a filter for a different score.
Operations should be flexible to be able to be able to implement new ones in the future if they prove useful, currently the main set would be add
, subtract
, multiply
, divide
, mod
, set
, min
, max
, random
.
Something else that could prove useful is the <maybe>
section in kits, since it would essentially allow for conditional flow in variable assignation, but i believe similar results can be acheived with a bit of work and multiple kits fenced behind filters.
Also there would be pgm-defined variables, these would all be namespaced with pgm:, and the namespace would be prohibited to use for maps. Examples could be things like pgm:tick
that would always have the current match tick, pgm:score
for the competitor score, pgm:lives
for amount of blitz lives. The idea is that you could make a kit give (or remove) score or lives etc.
Edit 1:
Modified kit syntax from variable to let, and variable declaration from variable to var.
Edit 2:
Added persist to player-scoped variables. and note about default-implemented & namespaced pgm variables.
What if we made the application syntax more concise? The operation
is the key and the amount is the value
.
<let id="progress" add="5"/>
What if we made the application syntax more concise? The
operation
is the key and the amount is thevalue
.<let id="progress" add="5"/>
let
is a better name for the kit, however, having the operations be different attributes leads to some unexpected behavior from the user side:
You may think add="5" multiply="10"
seems completely reasonable, however, according to XML specification https://www.w3.org/TR/REC-xml/
the order of attribute specifications in a start-tag or empty-element tag is not significant
Which means add="5" multiply="10"
should have the same behavior as multiply="5" add="10"
, that's not what the mapmaker will expect the system to do though.
That leads to the only other option: you must have one and only one operation attribute per tag, at which point, i'm not convinced that we're gaining anything by having N different attributes, over having 2, one of which is an enum of allowed values.
Also, regarding id
directing to the variable id, i'm just afraid of it becoming a conflict in the future as you're using "id" as "id reference of the variable" and not "id of the let
".
this has been merged