[Release] Control Point Victory

[Release] Control Point Victory

Discuss Lua based Spring scripts (LuaUI widgets, mission scripts, gaia scripts, mod-rules scripts, scripted keybindings, etc...)

Moderator: Moderators

Post Reply
User avatar
Forboding Angel
Evolution RTS Developer
Posts: 14673
Joined: 17 Nov 2005, 02:43

[Release] Control Point Victory

Post by Forboding Angel »

Most of you already know about this gadget, but there have been a TON of improvements to it. I've been working on it since February, and with the help of Code_Man, Smoth, and Lurker, I believe it is in a good enough place for a release.

First off, let me explain it a bit:

Control Points are spread throughout the map. The points can be captured by simply moving units into the circle. It’s very similar to how Dawn of War or Battlefield control points works. Probably more similar to Battlefield. You and your opponent(s) start with a maximum score (by default right now it is 3500). For each Control Point that your opponent controls, you will lose that many points from your score every second. There are x points on each map that can be captured. This causes you to need to move out as quickly as possible, and you will find that you constantly are fighting over control points. When a player reaches a score of 0, that player’s units will explode. This makes for some very intense and exciting games, and in testing we have had a ton of fun with them.

Additionally, there are 3 Control Victory modes:
  • Countdown
    Tug of War
    Domination
Countdown is the game mode that I just described. Both player’s score counts down until someone hits 0.

Tug of war causes the points to be transferred from one player to another but with a small catch… Point values are doubled (by default... can be changed via modoption), meaning that if you own 7 points, you will receive 14 score points from your opponent every second.

Domination requires that you own all of the Control Points for 30 seconds. If you accomplish this then you score 1000 points, at which point all of the Control Points capture status is reset (in other words all points go neutral after a score). First player to 3500 points wins!

All of the parameters are highly configurable from the lobby via modoptions, and you can change nearly everything about the gameplay with these configuration options.

----

The gadget itself has a LOT of documentation directly inside of it as well.

Code: Select all

--[[
-------------------
Before implementing this gadget, read this!!!
This gadget relies on three parts:
• control point config file which is located in luarules/configs/controlpoints/ , and it must have a filename of cv_<mapname>.lua. So, in the case of a map named "Iammas Prime -" with a version of "v01", then the name of my file would be "cv_Iammas Prime - v01.lua".
	PLEASE NOTE: If the map config file is not found and a capture mode is selected, the gadget will generate 7 points in a circle on the map automagically.
• config placed in luarules/configs/ called cv_nonCapturingUnits.lua
• config placed in luarules/configs/ called cv_buildableUnits.lua
• modoptions

The control point config is structured like this (cv_Iammas Prime - v01.lua):

////

return {
	points = { 
		[1] = {x = 4608, y = 0, z = 3048},
		[2] = {x = 4265, y = 0, z = 1350},
		[3] = {x = 4950, y = 0, z = 4786},
		[4] = {x = 6641, y = 0, z = 858},
		[5] = {x = 2574, y = 0, z = 5271},
		[6] = {x = 2219, y = 0, z = 498},
		[7] = {x = 6993, y = 0, z = 5616},
	},
}

////

The nonCapturingUnits.lua config file is structured like this:
These are units that are not allowed to capture points.

////

local nonCapturingUnits = {
	"eairengineer",
	"efighter",
	"egunship2",
	"etransport",
	"edrone",
	"ebomber",
}

return nonCapturingUnits

////

The buildableUnits.lua config file is structured like this:
These are units that are allowed to be built within control points.

////

local buildableUnits = {
	"armamex",
	"armmex",
	"armmoho",
	"armuwmex",
	"armuwmme",
	"corexp",
	"cormex",
	"cormexp",
	"cormoho",
	"coruwmex",
	"coruwmme",
}

return buildableUnits

////

Here are all of the modoptions in a neat copy pastable form... Place these modoptions in modoptions.lua in your base game folder:

////
-- Control Victory Options	
	{
		key    = 'controlvictoryoptions',
		name   = 'Control Victory Options',
		desc   = 'Allows you to control at a granular level the individual options for Control Point Victory',
		type   = 'section',
	},
	{
		key="scoremode",
		name="Scoring Mode (Control Victory Points)",
		desc="Defines how the game is played",
		type="list",
		def="countdown",
		section="controlvictoryoptions",
		items={
			{key="disabled", name="Disabled", desc="Disable Control Points as a victory condition."},
			{key="countdown", name="Countdown", desc="A Control Point decreases all opponents' scores, zero means defeat."},
			{key="tugofwar", name="Tug of War", desc="A Control Point steals enemy score, zero means defeat."},
			{key="domination", name="Domination", desc="Holding all Control Points will grant 1000 score, first to reach the score limit wins."},
		}
	},	
	{
		key    = 'limitscore',
		name   = 'Total Score',
		desc   = 'Total score amount available.',
		type   = 'number',
		section= 'controlvictoryoptions',
		def    = 2750,
		min    = 500,
		max    = 5000,
		step   = 1,  -- quantization is aligned to the def value
		-- (step <= 0) means that there is no quantization
	},
	{
		key    = 'captureradius',
		name   = 'Capture Radius',
		desc   = 'Radius around a point in which to capture it.',
		type   = 'number',
		section= 'controlvictoryoptions',
		def    = 500,
		min    = 100,
		max    = 1000,
		step   = 25,  -- quantization is aligned to the def value
		-- (step <= 0) means that there is no quantization
	},
		{
		key    = 'capturetime',
		name   = 'Capture Time',
		desc   = 'Time to capture a point.',
		type   = 'number',
		section= 'controlvictoryoptions',
		def    = 30,
		min    = 1,
		max    = 60,
		step   = 1,  -- quantization is aligned to the def value
		-- (step <= 0) means that there is no quantization
	},
		{
		key    = 'capturebonus',
		name   = 'Capture Bonus',
		desc   = 'How much faster capture takes place by adding more units.',
		type   = 'number',
		section= 'controlvictoryoptions',
		def    = 0.5,
		min    = 0,
		max    = 10,
		step   = 0.1,  -- quantization is aligned to the def value
		-- (step <= 0) means that there is no quantization
	},
		{
		key    = 'decapspeed',
		name   = 'De-Cap Speed',
		desc   = 'Speed multiplier for neutralizing an enemy point.',
		type   = 'number',
		section= 'controlvictoryoptions',
		def    = 3,
		min    = 0.1,
		max    = 10,
		step   = 0.1,  -- quantization is aligned to the def value
		-- (step <= 0) means that there is no quantization
	},
		{
		key    = 'starttime',
		name   = 'Start Time',
		desc   = 'The time when capturing can start.',
		type   = 'number',
		section= 'controlvictoryoptions',
		def    = 0,
		min    = 0,
		max    = 300,
		step   = 1,  -- quantization is aligned to the def value
		-- (step <= 0) means that there is no quantization
	},
		{
		key    = 'metalperpoint',
		name   = 'Metal given to each player per captured point',
		desc   = 'Each player on an allyteam that has captured a point will receive this amount of resources per point captured per second',
		type   = 'number',
		section= 'controlvictoryoptions',
		def    = 0,
		min    = 0,
		max    = 20,
		step   = 1,  -- quantization is aligned to the def value
		-- (step <= 0) means that there is no quantization
	},
		{
		key    = 'energyperpoint',
		name   = 'Energy given to each player per captured point',
		desc   = 'Each player on an allyteam that has captured a point will receive this amount of resources per point captured per second',
		type   = 'number',
		section= 'controlvictoryoptions',
		def    = 0,
		min    = 0,
		max    = 20,
		step   = 1,  -- quantization is aligned to the def value
		-- (step <= 0) means that there is no quantization
	},
		{
		key    = 'dominationscoretime',
		name   = 'Domination Score Time',
		desc   = 'Time needed holding all points to score in multi domination.',
		type   = 'number',
		section= 'controlvictoryoptions',
		def    = 30,
		min    = 1,
		max    = 60,
		step   = 1,  -- quantization is aligned to the def value
		-- (step <= 0) means that there is no quantization
	},
		{
		key    = 'tugofwarmodifier',
		name   = 'Tug of War Modifier',
		desc   = 'The amount of score transfered between opponents when points are captured is multiplied by this amount.',
		type   = 'number',
		section= 'controlvictoryoptions',
		def    = 2,
		min    = 0,
		max    = 6,
		step   = 1,  -- quantization is aligned to the def value
		-- (step <= 0) means that there is no quantization
	},
-- End Control Victory Options
////


That's all folks!!!
-------------------
]]--
Team Colors
When you are playing a team game with this, the gadget looks at your ally team, chooses the first player on that team, grabs that player's color and uses it for the teamcolor on the scoreboard. This means that the points captured by that ally team and the scoreboard will reflect that one person's color.

It's a lot harder to explain it than for you to simply see it. It makes perfect sense when you see it first hand.

Image

Image

Image

The best part about this gadget is that it is completely standalone and can be implemented easily into any game for extra gameplay goodness, so, enjoy!!! It only took the better part of 6 months to get it into any kind of shape for public consumption :roll:

Gadget Repo:
https://github.com/Spring-Helper-Projec ... rolVictory
Last edited by Forboding Angel on 22 Sep 2016, 07:21, edited 3 times in total.
User avatar
Forboding Angel
Evolution RTS Developer
Posts: 14673
Joined: 17 Nov 2005, 02:43

Re: [Release] Control Point Victory

Post by Forboding Angel »

Updated to display the current scoring mode and add a new parameter to tug of war (modifier for point transfer rates)

Image
Google_Frog
Moderator
Posts: 2464
Joined: 12 Oct 2007, 09:24

Re: [Release] Control Point Victory

Post by Google_Frog »

Looks good. It looks like a much more complete take on the old king of the hill mode. I suggest that you move everything out of the unsynced part of the gadget and into a widget. Communicate all the required data via GameRulesParams. Here are some benefits:
  • AIs can read GameRulesParams (I think) so will be able to see control point location and scoreboard status.
  • Widgets provide a much better UI framework for the scoreboard. For example a widget could be written with Chili to display the scoreboard based on a few GameRulesParams.
  • Configuration of the control point drawing. Possibly high/low graphics options.
  • I have been led to believe that data transfer from synced gadgets to unsynced gadgets is slow. Especially if you do it while drawing.
User avatar
Forboding Angel
Evolution RTS Developer
Posts: 14673
Joined: 17 Nov 2005, 02:43

Re: [Release] Control Point Victory

Post by Forboding Angel »

It was my intention to eventually move anything unsynced to a widget (I.E. all the drawing). There are a lot more benefits than you mentioned, but I've already been working on it since february and atm it is in a state that is complete and functioning so I figured release early, release often :-)

Lurker already did some groundwork on widgetizing it

Code: Select all

in a gadget's update:
if Script.LuaUI.GetSyncedData then
    Script.LuaUI.GetSyncedData{
        score = SYNCED.score
        dom = SYNCED.dom
    }
end
in a widget:
local function GetSyncedData(data)
    WG.SyncedData = data
end
function widget:Initialize()
    widgetHandler:RegisterGlobal('GetSyncedData', GetSyncedData)
end
function widget:Shutdown()
    widgetHandler:DeregisterGlobal('GetSyncedData')
end
in other widgets make sure WG.SyncedData exists before using it
I'm not 100% sure if you can send tables that way but we'll find out
As I understand it, we would need a go-between widget to facilitate communication between synced/unsynced. Doing this is the eventual goal. If you feel like helping me do it, then by all means hell yes :-)

I would like to have a drawing widget that is non-chili and one that is chili. Simply because if the maintainers of chili can't be bothered to actually maintain the source repos of chili, then there are a lot of times where it can't be realistically trusted (I kind of see Jools' point here, but I don't necessarily agree with his non-chili approach). I intended this to be a drop in, as in it just works. The chili widget could be put next to the non-chili so that that way there is a version that works without any outside necessities. Hopefully my reasoning makes sense.

In case it doesn't... I gutted evo in february. I completely gutted it and took out any of the old stuff and replaced it from source. LUPS, Chili, CUS, etc. As a result i have found t hat many of these source repos are poorly maintained if at all, and frankly, it makes me a bit angry. As a project, we should all be fucking ashamed of ourselves. These are core elements that are just left to rot and in order to get proper versions of them it is necessary to raid one of the games. That is completely unacceptable.
gajop
Moderator
Posts: 3051
Joined: 05 Aug 2009, 20:42

Re: [Release] Control Point Victory

Post by gajop »

Glad you managed to sort out the issues and make a release out of it.

1) I would suggest you look at MCL's beacons as they have a similar capture mechanic.
I think it's worth separating the beacon/capture point logic from the victory conditions. I have spent some time making the capture points in MCL prettier, and I think it will take considerable effort to make it anywhere as good as in AAA games.
A lot of stuff is potentially reusable.

2) Chili/LUPS/CUS: it's the simple case of no one contributing upstream. It seems it's very tempting to make game-specific changes that are not mergable, and thus cause divergence. /shrug
User avatar
Forboding Angel
Evolution RTS Developer
Posts: 14673
Joined: 17 Nov 2005, 02:43

Re: [Release] Control Point Victory

Post by Forboding Angel »

Ok, so it's worth noting that this post deserves a HUGE update.
Latest version of the gadget is here: https://github.com/EvolutionRTS/Evoluti ... ictory.lua

A TON of things have been fixed, so any buggy behavior you have experienced in the past has been dealt with.

Big thanks to Sprung for helping me today.

CV now has the ability to have a config that lists units that can be built in a cv point.

Also, and possibly more importantly, CV now has the ability to reward resources to every single player on the allyteam who owns a point. So if the game is a 5v5 BADSD, and each point gives 5 metal, then that means that if Team A captures a point, each person on that team will get a boost of 5 metal to their income (energy can be rewarded as well, ofc). So that is an influx of +25 for the entire team (split between players ofc).

Point autogeneration... A config is no longer necessary, nor even needed tbh. 7 points will now be distributed around the map in a circle, with one directly in the center of the map. Points on DD now get autodistributed like this:
Image

In the gadget are VERY DETAILED instructions on what you have to do to implement it. Shouldn't take more than about 3 minutes to implement in any game.

Enjoy!

Code: Select all

--[[
-------------------
Before implementing this gadget, read this!!!
This gadget relies on three parts:
• control point config file which is located in luarules/configs/controlpoints/ , and it must have a filename of cv_<mapname>.lua. So, in the case of a map named "Iammas Prime -" with a version of "v01", then the name of my file would be "cv_Iammas Prime - v01.lua".
	PLEASE NOTE: If the map config file is not found and a capture mode is selected, the gadget will generate 7 points in a circle on the map automagically.
• config placed in luarules/configs/ called cv_nonCapturingUnits.lua
• config placed in luarules/configs/ called cv_buildableUnits.lua
• modoptions

The control point config is structured like this (cv_Iammas Prime - v01.lua):

////

return {
	points = { 
		[1] = {x = 4608, y = 0, z = 3048},
		[2] = {x = 4265, y = 0, z = 1350},
		[3] = {x = 4950, y = 0, z = 4786},
		[4] = {x = 6641, y = 0, z = 858},
		[5] = {x = 2574, y = 0, z = 5271},
		[6] = {x = 2219, y = 0, z = 498},
		[7] = {x = 6993, y = 0, z = 5616},
	},
}

////

The nonCapturingUnits.lua config file is structured like this:
These are units that are not allowed to capture points.

////

local nonCapturingUnits = {
	"eairengineer",
	"efighter",
	"egunship2",
	"etransport",
	"edrone",
	"ebomber",
}

return nonCapturingUnits

////

The buildableUnits.lua config file is structured like this:
These are units that are allowed to be built within control points.

////

local buildableUnits = {
	"armamex",
	"armmex",
	"armmoho",
	"armuwmex",
	"armuwmme",
	"corexp",
	"cormex",
	"cormexp",
	"cormoho",
	"coruwmex",
	"coruwmme",
}

return buildableUnits

////

Here are all of the modoptions in a neat copy pastable form... Place these modoptions in modoptions.lua in your base game folder:

////
-- Control Victory Options	
	{
		key    = 'controlvictoryoptions',
		name   = 'Control Victory Options',
		desc   = 'Allows you to control at a granular level the individual options for Control Point Victory',
		type   = 'section',
	},
	{
		key="scoremode",
		name="Scoring Mode (Control Victory Points)",
		desc="Defines how the game is played",
		type="list",
		def="countdown",
		section="controlvictoryoptions",
		items={
			{key="disabled", name="Disabled", desc="Disable Control Points as a victory condition."},
			{key="countdown", name="Countdown", desc="A Control Point decreases all opponents' scores, zero means defeat."},
			{key="tugofwar", name="Tug of War", desc="A Control Point steals enemy score, zero means defeat."},
			{key="domination", name="Domination", desc="Holding all Control Points will grant 1000 score, first to reach the score limit wins."},
		}
	},	
	{
		key    = 'limitscore',
		name   = 'Total Score',
		desc   = 'Total score amount available.',
		type   = 'number',
		section= 'controlvictoryoptions',
		def    = 2750,
		min    = 500,
		max    = 5000,
		step   = 1,  -- quantization is aligned to the def value
		-- (step <= 0) means that there is no quantization
	},
	{
		key    = 'captureradius',
		name   = 'Capture Radius',
		desc   = 'Radius around a point in which to capture it.',
		type   = 'number',
		section= 'controlvictoryoptions',
		def    = 500,
		min    = 100,
		max    = 1000,
		step   = 25,  -- quantization is aligned to the def value
		-- (step <= 0) means that there is no quantization
	},
		{
		key    = 'capturetime',
		name   = 'Capture Time',
		desc   = 'Time to capture a point.',
		type   = 'number',
		section= 'controlvictoryoptions',
		def    = 30,
		min    = 1,
		max    = 60,
		step   = 1,  -- quantization is aligned to the def value
		-- (step <= 0) means that there is no quantization
	},
		{
		key    = 'capturebonus',
		name   = 'Capture Bonus',
		desc   = 'How much faster capture takes place by adding more units.',
		type   = 'number',
		section= 'controlvictoryoptions',
		def    = 0.5,
		min    = 0,
		max    = 10,
		step   = 0.1,  -- quantization is aligned to the def value
		-- (step <= 0) means that there is no quantization
	},
		{
		key    = 'decapspeed',
		name   = 'De-Cap Speed',
		desc   = 'Speed multiplier for neutralizing an enemy point.',
		type   = 'number',
		section= 'controlvictoryoptions',
		def    = 3,
		min    = 0.1,
		max    = 10,
		step   = 0.1,  -- quantization is aligned to the def value
		-- (step <= 0) means that there is no quantization
	},
		{
		key    = 'starttime',
		name   = 'Start Time',
		desc   = 'The time when capturing can start.',
		type   = 'number',
		section= 'controlvictoryoptions',
		def    = 0,
		min    = 0,
		max    = 300,
		step   = 1,  -- quantization is aligned to the def value
		-- (step <= 0) means that there is no quantization
	},
		{
		key    = 'metalperpoint',
		name   = 'Metal given to each player per captured point',
		desc   = 'Each player on an allyteam that has captured a point will receive this amount of resources per point captured per second',
		type   = 'number',
		section= 'controlvictoryoptions',
		def    = 0,
		min    = 0,
		max    = 20,
		step   = 1,  -- quantization is aligned to the def value
		-- (step <= 0) means that there is no quantization
	},
		{
		key    = 'energyperpoint',
		name   = 'Energy given to each player per captured point',
		desc   = 'Each player on an allyteam that has captured a point will receive this amount of resources per point captured per second',
		type   = 'number',
		section= 'controlvictoryoptions',
		def    = 0,
		min    = 0,
		max    = 20,
		step   = 1,  -- quantization is aligned to the def value
		-- (step <= 0) means that there is no quantization
	},
		{
		key    = 'dominationscoretime',
		name   = 'Domination Score Time',
		desc   = 'Time needed holding all points to score in multi domination.',
		type   = 'number',
		section= 'controlvictoryoptions',
		def    = 30,
		min    = 1,
		max    = 60,
		step   = 1,  -- quantization is aligned to the def value
		-- (step <= 0) means that there is no quantization
	},
		{
		key    = 'tugofwarmodifier',
		name   = 'Tug of War Modifier',
		desc   = 'The amount of score transfered between opponents when points are captured is multiplied by this amount.',
		type   = 'number',
		section= 'controlvictoryoptions',
		def    = 2,
		min    = 0,
		max    = 6,
		step   = 1,  -- quantization is aligned to the def value
		-- (step <= 0) means that there is no quantization
	},
-- End Control Victory Options
////


That's all folks!!!
-------------------
]]--
User avatar
MasterBel2
Posts: 347
Joined: 11 Apr 2016, 12:03

Re: [Release] Control Point Victory

Post by MasterBel2 »

Hmm looks cool. Only issue is that two of the points seem to lean towards east, or at least be more accessible for them. But this might only be a DSD issue.
User avatar
Forboding Angel
Evolution RTS Developer
Posts: 14673
Joined: 17 Nov 2005, 02:43

Re: [Release] Control Point Victory

Post by Forboding Angel »

Now has it's own repository, and new visuals (thanks Floris!)
https://github.com/Spring-Helper-Projec ... rolVictory

Image

Image
Post Reply

Return to “Lua Scripts”