The Hacksperiment [Community Project]

General discussion about LÖVE, Lua, game development, puns, and unicorns.
User avatar
kbmonkey
Party member
Posts: 139
Joined: Tue Sep 01, 2015 12:19 pm
Location: Sydney
Contact:

Re: The Hacksperiment [Community Project]

Post by kbmonkey »

MadByte wrote:
TheOdyssey wrote:So we can just add in basically whatever?
Basically yes, as long as it works. I need to say that this experiment is kind of based on trust that nobody just want to troll everyone else. And as every experiment this can fail hard - but why shouldn't we try it at least ?
Fork the project and make Pull requests so everyone can see if there is troll-code before you merge into the main branch. :megagrin:
User avatar
kbmonkey
Party member
Posts: 139
Joined: Tue Sep 01, 2015 12:19 pm
Location: Sydney
Contact:

Re: The Hacksperiment [Community Project]

Post by kbmonkey »

I have created a pull request for my first module. It is not very glamorous sorry to say:

This is a unit test module that runs through a couple of the Game: functions.

Engage the tests by smashing down `F10`.

You will see an error that reveals a bug in the `Game:getModule()` function :)

https://github.com/MadByteDE/The-Hacksperiment/pull/1
User avatar
MadByte
Party member
Posts: 533
Joined: Fri May 03, 2013 6:42 pm
Location: Braunschweig, Germany

Re: The Hacksperiment [Community Project]

Post by MadByte »

Thanks, I'll look into it.
User avatar
Taehl
Dreaming in associative arrays
Posts: 1025
Joined: Mon Jan 11, 2010 5:07 am
Location: CA, USA
Contact:

Re: The Hacksperiment [Community Project]

Post by Taehl »

MadByte wrote: The idea is good and I would be very proud if we can establish something that epic [...]

I'm not sure if my base structure of the project fit to such an ambitious project. We'll see.
I'm still working on it (it needs a lot of polish and testing!), but it IS currently functional (sans the content pack system). If you'd like to play around with a preview, here's my current TLECS.lua:

Code: Select all

-- TLECS v0.1b, an extensible Entity-Component System implementation in Lua
-- by Taehl (email.Taehl@gmail.com)

-- TODO: content pack system
	-- it'll have to be able to add/override nodes and systems
		-- when adding a node, also add components[node] = {}!

local TLECS = {}		-- namespace
TLECS.nodes = {}	-- nodes are prototypes for components, representing default state
TLECS.ents = {}		-- entities are numerical indices that link components
-- later, the ent itself may do more than isDead. Ideally, I'd like to be able to add tags to ents for better cross-content support
TLECS.components = {}	-- components are instanced per-ent, holding their state
-- each TLECS.components lists all ents possessing that component (much faster to iterate with rather than all ents!) (may possibly be replaced by the tag system?)
TLECS.systems = {}	-- systems are functions which iterate on components
TLECS.contents = {}	-- content populates nodes/components with data and systems with code

for node, v in pairs( TLECS.nodes ) do TLECS.components[node] = {} end


-- import contents into ECS
-- if fresh is true, all existing TLECS data will be replaced by ONLY contents (good when starting a new game)
-- otherwise, all content will be overlaid (best for adding new content, expanding others' content, etc.)
function TLECS.importContents( contents, fresh )
	contents = contents or TLECS.contents
	if fresh then
		TLECS.nodes = {}
		TLECS.ents = {}
		TLECS.components = {}
		TLECS.systems = {}
		for node, v in pairs( TLECS.nodes ) do TLECS.components[node] = {} end
	end
	for kind, adds in pairs( contents ) do
		for new, data in pairs( adds ) do
			TLECS[kind][new] = data
		end
	end
end


-- spawn an entity with given parameters
-- example: spawnEnt( { pos={ x=2, y=5 }, draw{ img=robot.png, scale= 2} } )
function TLECS.spawnEnt( comps )
	if not comps then error"Can't spawnEnt with no components!" end
	local ent = {}
	for component,data in pairs( comps ) do
		TLECS.addComponent( ent, component, data )
	end
	table.insert( TLECS.ents, {} )		-- ent, if ents are to list their components...
	return ent
end


--  adds a component to an existing object
--	returns the new component
function TLECS.addComponent( ent, component, data )
	if not (ent and component) then error"Can't addComponent without ent and component!" end
	-- instance the components from their nodes
	local comp = { parent = ent }
	for k,v in pairs( TLECS.nodes[component] ) do
		v = data[k] or v		-- if data was specified then add it, else use default
		comp[k] = v
	end
	ent[component] = comp
	table.insert( TLECS.components[component], comp )
	return comp
end


--	removes a component from an existing ent
--	returns true if it was removed, false if ent didn't have it
function TLECS.removeComponent( ent, component )
	if not (ent and component) then error"Can't removeComponent without ent and component!" end
	ent[component] = nil
	for k,v in TLECS.components do
		if v == ent then
			table.remove( TLECS.components[component], v )
			return true
		end
	end
end


-- systems execution and ent clean-up
function TLECS.update(dt)
	-- run each system on TLECS.ents with the requisite component
	for k,system in pairs( TLECS.systems ) do
		for k, comp in ipairs( TLECS.components[system.requires] or {} ) do
			system.run( comp, dt )		-- todo: support return values? (where would they be sent? callbacks?)
		end
	end	
	
	-- remove dead TLECS.ents
	for k = #TLECS.ents,1, -1 do
		local ent = TLECS.ents[k]
		if ent.isDead then
			table.remove(TLECS.ents, k)
			-- remove ent from all components' lists
			for component, entlist in pairs( TLECS.components ) do
				for k, v in pairs( entlist ) do
					if v == ent then
						table.remove( component, k )
						break
					end
				end
			end
		end
	end
end


return TLECS
Content is put in tables following naming convention, like so:

Code: Select all

content = {
	nodes = {
		-- engine nodes
		draw = { img = whatever, m=0, color={255,255,255} },
		pos = { x=0, y=0, },
		move = { vx=0, vy=0, g=.98, airf=.001, groundf=2.99, },
		
		-- character nodes
		stats = { topSpeed=200, accel=50, },
		state = { is = "standing", running = false, dreaming = true },
		
		-- level nodes
		wall = { x1=0, y1=0, x2=0, y2=0 }
	}

	systems = {
		draw = {
			requires = nil,	-- don't run in TLECS.update(), since we'd probably want this in love.draw()
			run = function( draw )
				local ent = draw.parent
				local lg = love.graphics
				if not ( ent.draw and ent.pos ) then return end
				
				if ent.move then draw.m = math.sign( ent.move.vx ) end	-- if it moves left, flip it
				lg.setColor( draw.color )
				lg.draw( draw.img, ent.pos.x, ent.pos.y, 0, 1*draw.m, 1, 16, 16 )
			end
		},
		
		lamePhysics = {
			requires = "move",
			run = function( move, dt )
				local ent = move.parent
				local pos = ent.pos
				pos.x, pos.y = pos.x + move.vx*dt, pos.y + (move.vy + move.g)*dt 
			end
		},
	}
}
Earliest Love2D supporter who can't Love anymore. Let me disable pixel shaders if I don't use them, dammit!
Lenovo Thinkpad X60 Tablet, built like a tank. But not fancy enough for Love2D 0.10.0+.
User avatar
MadByte
Party member
Posts: 533
Joined: Fri May 03, 2013 6:42 pm
Location: Braunschweig, Germany

Re: The Hacksperiment [Community Project]

Post by MadByte »

I just added a new callback "enter".
It will be triggered after all modules has been loaded properly. It can be used for stuff like that:

Code: Select all

function myModule:enter()
  local world = Game:getModule("PublicWorld")
  world:add(self:new(100, 100)) -- adds your module as an entity to another module
end
And there is a new "Mini Wiki" with two pages (Module Documentation, List of Modules). You can find it on top of the OP
or in the Github Readme.
User avatar
kbmonkey
Party member
Posts: 139
Joined: Tue Sep 01, 2015 12:19 pm
Location: Sydney
Contact:

Re: The Hacksperiment [Community Project]

Post by kbmonkey »

Been trying for an idea of what to add, but my brain is coming up emtpy - it is driving me nuts :crazy:
User avatar
MadByte
Party member
Posts: 533
Joined: Fri May 03, 2013 6:42 pm
Location: Braunschweig, Germany

Re: The Hacksperiment [Community Project]

Post by MadByte »

kbmonkey wrote:Been trying for an idea of what to add, but my brain is coming up emtpy - it is driving me nuts :crazy:
Pretty common problem for me as well. :ultrahappy:

I'd like to say that it does not matter what you add and if it fits to the theme of other modules. Just - be creative. The experiment is (at least for me) about how others react to your module(s) and about what they come up with - may talk about it, expand it and then build on top of stuff created by you and other people. Like there is no real way to go - just doing something togehter. The result can either be a total mess or something working - useable. It is not meant to get a specific kind of game, just meant to get .. something, you know.
The project is also not made for people who want to create something specific.

Not sure if that makes any sense :)
User avatar
kbmonkey
Party member
Posts: 139
Joined: Tue Sep 01, 2015 12:19 pm
Location: Sydney
Contact:

Re: The Hacksperiment [Community Project]

Post by kbmonkey »

I felt like doing something with angles so I built a nasty turret that fires missiles.

Gif in action

The turret has a function you can use to check if a blast hit anything:

Code: Select all

      turret = Game:getModule("turret")
      hit = turret:hit(self.x, self.y, self.radius)
Yep that is one ugly looking turret. But it packs a punch. Maybe some nice looking sprites can replace it :crazy:

Note: Code does not modify the MadAvatar module. I only did that for the gif.
User avatar
MadByte
Party member
Posts: 533
Joined: Fri May 03, 2013 6:42 pm
Location: Braunschweig, Germany

Re: The Hacksperiment [Community Project]

Post by MadByte »

kbmonkey wrote:I felt like doing something with angles so I built a nasty turret that fires missiles.
Gif in action
challenge accepted :cool:
Waves of my avatar to kill!
(need some more polishing)
User avatar
kbmonkey
Party member
Posts: 139
Joined: Tue Sep 01, 2015 12:19 pm
Location: Sydney
Contact:

Re: The Hacksperiment [Community Project]

Post by kbmonkey »

MadByte wrote:
kbmonkey wrote:I felt like doing something with angles so I built a nasty turret that fires missiles.
Gif in action
challenge accepted :cool:
Waves of my avatar to kill!
(need some more polishing)
Nice one! Great use of the hit() call :)

I replaced that ugly turret with a sprite from here: http://opengameart.org/content/steampunk-turrets

Image
Post Reply

Who is online

Users browsing this forum: No registered users and 6 guests