Jump to content

ShadowRadience

Members
  • Posts

    15
  • Joined

  • Last visited

Posts posted by ShadowRadience

  1. That's my script. You are supposed to have 5 prefabs with specified entry and exit pivots. And a start pivot as a beginning of a dungeon.

    But I don't know what have you changed.

     

    Edit: Have you just typed a string value in startPivot variable? You should drag a pivot entity in the scene on this variable in the inspector.

    I changed the code "if App.window:KeyHit(Key.G)then self:Use()end" to "if window:KeyHit(Key.G)" along with the console print thing to just print. and i typed in the strng for start pivot, what ive done using your code is, i made a base room, put the player in it, added a pivot at the entrance and put the script onto it, then i just put a pivot at every other prefabs entrance and exit, i got it to work at one point(like just being able to run the game without errors) and then i pressed g and well, nothing happened anywhere in the map. The only script attached to any of the pivots are the one in the player spawn room. and then the rest are just plain pivots nothing attached, no renames. So, if i repaste your original code into a script and change the location names for the prefabs and saved the script it would be the exact same thing as your original one, but with this :

    [/font]
    [size=2][size=4][font=arial,helvetica,sans-serif]Script.d1="Prefabs/Dungeon/d1.pfb"
    Script.d2l="Prefabs/Dungeon/d2l.pfb"
    Script.d2r="Prefabs/Dungeon/d2r.pfb"
    Script.d3l="Prefabs/Dungeon/d3l.pfb"
    Script.d3r="Prefabs/Dungeon/d3r.pfb"
    

    [/size][/size]

    changed to something like this

    Script.d1="Prefabs/Dungeon/Room5.pfb"
    Script.d2l="Prefabs/Dungeon/Room4.pfb"
    Script.d2r="Prefabs/Dungeon/Room3.pfb"
    Script.d3l="Prefabs/Dungeon/Room2.pfb"
    Script.d3r="Prefabs/Dungeon/Room1.pfb"
    

    and then all i would do is say i want the player to start in room 1 i would put a pivot at room ones entrance(there would be no exit on this one just one exit point) and attach the script you made to it, and then save that room as a prefab named Room1 in the Prefabs/Dungeon/Room1.pfb and then place it in the scene, and then all the other prefabs would just have plain old normal pivots at the entrance and exit for each one?

  2. That is a lot of code to go through.

     

    I am still learning Lua as well and I am very inexperienced but here is my guess as to why you are getting an issue with 'startPivot'.

     

    There are scripts at the very start of the code that you are calling within this script.

     

    'startPivot' is it's own script that you are calling within this script. You are getting a 'nil' value because it cannot find 'startPivot'.

     

    My guess would be that even if you fix that you would get further issues because throughout the code you are using scripts and calling functions that are supposed to be defined within those other scripts.

     

    Then again I could be completely wrong.

     

    I am still learning myself and that code above looks big and scary sad.png

     

    Kudos though for the time and effort you have put in, that is some dedication right there!

    I appreciate it! Thanks! I think i may just go through trial and error with making a completely original script for it.

  3. This isn't so much of a game dev challenge as it is an algorithm issue. It's easy to avoid making rooms not intersect by using a 2D or 3D array. The difficult part is making the result be what you want. You need to define how you want the procedural generation to go.

     

    In particular, I would look at these:

    https://en.wikipedia.org/wiki/Category:Graph_algorithms

     

    I would particularly look at the minimum spanning tree ones:

    https://en.wikipedia.org/wiki/Kruskal%27s_algorithm

    https://en.wikipedia.org/wiki/Prim%27s_algorithm

     

    Then, you should have a decent base to create this. But you still need to position the nodes and stuff. It can get somewhat complicated on the conceptual end or the coding end, so if you haven't programmed before, then this might not be the best project to start out with.

    Well ive programmed in other languages honestly couple years back i picked up C++ for a year, i studied HML CSS LESS Javscript, ruby and SASS in highschool, i tried java not really a fan, im thinking that maybe i should just pick up C++ again and use cpp instead of lua(i have all the DLC, i just thought lua was easier, but considering how flexible C++ is it might be the way i should go.) Before that though, i think im gunna give Programming in LUA Third Edition a read and hope i can figure it out cuz id rather not switch to C++.

    Wedmer posted a procedural generation script in the Workshop

     

    http://www.leadwerks.com/werkspace/page/viewitem?fileid=543847683

     

    I haven't had a look at it myself but it would be a good place to start.

    I appreciate it, i read the tutorial flexman did about this tutorial on the workshop, i also read the code that was in that workshop files(if i remember it was Main.lua and Test.lua) but its not what i wanna do, thats generating terrain without the use of prefabs, im trying to do it with prefabs so i have more control over how things will spawn in the map.

     

    Edit: I just read Programming in LUA Third Edition, and watch an hour long "Lua in one video" video, and i still dont have the slightest clue how to do this? Do i have to somehow store prefabs in a table and then call that table to generate it on Script:UpdateWorld()? If i did that wouldnt the world just keep generating new prefabs every frame, that would be an issue. I dont know, if anyone has any help, i could sure use it. Thanks in advance. I tried this code from another forum:

    Script.startPivot="" --entity
    Script.dungeon={}
    Script.names={"d1", "d2l", "d2r", "d3l", "d3r"} --Names of all possible dungeon segments to check AABB intersection
    Script.d1="Prefabs/Dungeon/d1.pfb"
    Script.d2l="Prefabs/Dungeon/d2l.pfb"
    Script.d2r="Prefabs/Dungeon/d2r.pfb"
    Script.d3l="Prefabs/Dungeon/d3l.pfb"
    Script.d3r="Prefabs/Dungeon/d3r.pfb"
    Script.currentR=0
    Script.nextR=0
    Script.j=0
    Script.i=0
    Script.s=0
    Script.allDungeonSegments={}
    --Debug
    function Script:Start()
    --math.randomseed(10)
    end
    function Script:UpdateWorld()
    if App.window:KeyHit(Key.G) then self:Use() end
    end
    function Script:Use()
    self:GenerateDungeon()
    end
    function Script:GenerateDungeon() --main generation function
    self.currentR=0
    self.nextR=0
    self.i=0
    self.j=0
    player:ConsoleLog("Generation started. Countentities = "..App.world:CountEntities())
    self:DeleteAllDungeonSegments()
    player:ConsoleLog("All segments deleted. Countentities = "..App.world:CountEntities())
    self.dungeon={}
    self.dungeon[0]=self:CreateSegment(self:GetRandomPart()) --Create first dungeon element
    self.dungeon[0]:SetRotation(0,self.currentR,0,true)
    local pos = self.dungeon[0]:FindChild("Enter"):GetPosition(true)
    local previousPos = self.startPivot:GetPosition(true)
    local dPos = pos-previousPos
    self.dungeon[0]:SetPosition(pos-dPos, true)
    local result = true --Create main path
    self.dungeon, result=self:GeneratePath(100, self.dungeon) --If this function failed to generate dungeon we still need to save it, but we sholdn't proceed further
    if not result then
    self:GenerateDungeon() --Failed to generate dungeon, starting again
    return
    end
    --Generate forks
    self:GenerateForks()
    end
    function Script:GeneratePath(amount, startingTable, emergencyLimit)
    if not emergencyLimit then emergencyLimit=200 end
    local dungeon={}
    dungeon=startingTable
    local emergencyCounter=0
    local i=#dungeon+1
    self.intersectionFound=false
    while i<=amount do
    emergencyCounter=emergencyCounter+1
    --System:Print(emergencyCounter.." i="..i)
    if emergencyCounter>emergencyLimit then --reached limit of retries, generate again
    return dungeon, false --still need to return current dungeon to be able to clear it
    end
    dungeon[i]=self:CreateSegment(self:GetRandomPart())
    local yRotation=dungeon[i-1]:GetRotation(true).y+self:GetExtraRotation(dungeon[i-1])
    dungeon[i]:SetRotation(0,yRotation,0,true)
    pos = dungeon[i]:FindChild("Enter"):GetPosition(true)
    previousPos = dungeon[i-1]:FindChild("Exit"):GetPosition(true)
    dPos = pos-previousPos
    dungeon[i]:SetPosition(dungeon[i]:GetPosition(true)-dPos, true)
    --Check AABB
    local aabb=dungeon[i]:GetAABB(Entity.GlobalAABB)
    local j=1
    local maximum=#self.allDungeonSegments
    while j<=maximum do
    --System:Print(j)
    if self.allDungeonSegments[j]~=dungeon[i] and self.allDungeonSegments[j]~=dungeon[i-1] and self.allDungeonSegments[j]~=dungeon[i-2] then
    if aabb:IntersectsAABB(self.allDungeonSegments[j]:GetAABB(Entity.GlobalAABB)) then
    System:Print(dungeon[i]:GetKeyValue("name").." intersects with "..self.allDungeonSegments[j]:GetKeyValue("name"))
    if i<4 then
    return dungeon, false
    else
    System:Print("Three steps back")
    self:DeleteSegment(dungeon[i])
    System:Print("Deleted last segment")
    dungeon[i]=nil
    self:DeleteSegment(dungeon[i-1])
    System:Print("Deleted i-1")
    dungeon[i]=nil
    self:DeleteSegment(dungeon[i-2])
    System:Print("Deleted i-2")
    dungeon[i]=nil
    i=i-3
    j=1000--maximum+1
    end
    end
    end
    j=j+1
    end
    i=i+1
    --System:Print("End of I loop. i="..i)
    end
    return dungeon, true --returning true if managed to generate dungeon properly
    end
    function Script:GenerateForks()
    local i=1
    while i <= #self.dungeon do
    if self.dungeon[i]:GetKeyValue("name")=="d1" and math.random(0, 20)==0 then
    local matrix=self.dungeon[i]:GetMatrix(true)
    self:DeleteSegment(self.dungeon[i])
    self.dungeon[i]={}
    self.dungeon[i][0]=self:CreateSegment(self:GetRandomPart(4,5))
    self.dungeon[i][0]:SetMatrix(matrix, true)
    self.dungeon[i][1]=self:CreateSegment(self:GetRandomPart())
    local yRotation=self.dungeon[i][0]:GetRotation(true).y+self:GetExtraRotation(self.dungeon[i][0]) --second element
    self.dungeon[i][1]:SetRotation(0,yRotation,0,true)
    pos = self.dungeon[i][1]:FindChild("Enter"):GetPosition(true)
    previousPos = self.dungeon[i][0]:FindChild("Exit2"):GetPosition(true)
    dPos = pos-previousPos
    self.dungeon[i][1]:SetPosition(self.dungeon[i][1]:GetPosition(true)-dPos, true)
    --local dungeon
    --local result
    local dungeon, result = self:GeneratePath(15, self.dungeon[i], 30)
    if not result then
    self:DeleteSegment(dungeon[#dungeon])
    self.dungeon[i]=dungeon
    else
    self.dungeon[i]=dungeon
    end
    end
    i=i+1
    end
    end
    --other function
    function Script:GetRandomPart(minimum, maximum) --Choose random element
    if not minimum then minimum=0; maximum=3 end
    local r=math.random(minimum, maximum)
    if r==1 or r==0 then
    return self.d1
    elseif r==2 then
    return self.d2r
    elseif r==3 then
    return self.d2l
    elseif r==4 then
    return self.d3r
    elseif r==5 then
    return self.d3l
    end
    end
    function Script:GetExtraRotation(name)
    name=name:GetKeyValue("name")
    if name=="d2r" or name=="d3r" then
    return (90)
    elseif name=="d2l" or name=="d3l" then
    return (-90)
    end
    return 0 --all other segments return 0
    end
    function Script:CreateSegment(name)
    local entity=Prefab:Load(name)
    table.insert (self.allDungeonSegments, entity)
    return entity
    end
    function Script:DeleteSegment(entity)
    local i=1
    local maximum=#self.allDungeonSegments
    while i<=maximum do
    if self.allDungeonSegments[i]==entity then
    local temp = self.allDungeonSegments[i]
    table.remove (self.allDungeonSegments, i)
    --self.allDungeonSegments[i]=0
    temp:Release()
    i=maximum
    end
    i=i+1
    end
    end
    function Script:DeleteAllDungeonSegments()
    for i=1, #self.allDungeonSegments do
    self.allDungeonSegments[i]:Release()
    end
    self.allDungeonSegments={}
    end
    function Script:IsDungeonSegment(name) --not needed
    name=name:GetKeyValue("name")
    for i=1, #self.names do
    if self.names[i]==name then return true end
    end
    return false
    end
    

    and i changed it to

    Script.startPivot="Exit2" --entity Starting Pivot
    Script.dungeon={}
    Script.names={"BaseRoom", "Hallway", "Intersection", "Corner", "Stairs"} --Names of all possible dungeon segments to check AABB intersection
    Script.BaseRoom="Prefabs/Dungeon/BaseRoom.pfb"
    Script.Hallway="Prefabs/Dungeon/Hallway.pfb"
    Script.Intersection="Prefabs/Dungeon/Intersection.pfb"
    Script.Corner="Prefabs/Dungeon/Corner.pfb"
    Script.Stairs="Prefabs/Dungeon/Stairs.pfb"
    Script.currentR=0
    Script.nextR=0
    Script.j=0
    Script.i=0
    Script.s=0
    Script.allDungeonSegments={}
    --Debug
    function Script:Start()
    --math.randomseed(10)
    end
    function Script:UpdateWorld()
    if window:KeyHit(Key.G) then
    self:Use()
    end
    end
    function Script:Use()
    self:GenerateDungeon()
    end
    function Script:GenerateDungeon() --main generation function
    self.currentR=0
    self.nextR=0
    self.i=0
    self.j=0
    print("Generation started. Countentities = "..world:CountEntities())
    self:DeleteAllDungeonSegments()
    print("All segments deleted. Countentities = "..world:CountEntities())
    self.dungeon={}
    self.dungeon[0]=self:CreateSegment(self:GetRandomPart()) --Create first dungeon element
    self.dungeon[0]:SetRotation(0,self.currentR,0,true)
    local pos = self.dungeon[0]:FindChild("Enter"):GetPosition(true)
    local previousPos = self.startPivot:GetPosition(true)
    local dPos = pos-previousPos
    self.dungeon[0]:SetPosition(pos-dPos, true)
    local result = true --Create main path
    self.dungeon, result=self:GeneratePath(100, self.dungeon) --If this function failed to generate dungeon we still need to save it, but we sholdn't proceed further
    if not result then
    self:GenerateDungeon() --Failed to generate dungeon, starting again
    return
    end
    --Generate forks
    self:GenerateForks()
    end
    function Script:GeneratePath(amount, startingTable, emergencyLimit)
    if not emergencyLimit then emergencyLimit=200 end
    local dungeon={}
    dungeon=startingTable
    local emergencyCounter=0
    local i=#dungeon+1
    self.intersectionFound=false
    while i<=amount do
    emergencyCounter=emergencyCounter+1
    --System:Print(emergencyCounter.." i="..i)
    if emergencyCounter>emergencyLimit then --reached limit of retries, generate again
    return dungeon, false --still need to return current dungeon to be able to clear it
    end
    dungeon[i]=self:CreateSegment(self:GetRandomPart())
    local yRotation=dungeon[i-1]:GetRotation(true).y+self:GetExtraRotation(dungeon[i-1])
    dungeon[i]:SetRotation(0,yRotation,0,true)
    pos = dungeon[i]:FindChild("Enter"):GetPosition(true)
    previousPos = dungeon[i-1]:FindChild("Exit"):GetPosition(true)
    dPos = pos-previousPos
    dungeon[i]:SetPosition(dungeon[i]:GetPosition(true)-dPos, true)
    --Check AABB
    local aabb=dungeon[i]:GetAABB(Entity.GlobalAABB)
    local j=1
    local maximum=#self.allDungeonSegments
    while j<=maximum do
    --System:Print(j)
    if self.allDungeonSegments[j]~=dungeon[i] and self.allDungeonSegments[j]~=dungeon[i-1] and self.allDungeonSegments[j]~=dungeon[i-2] then
    if aabb:IntersectsAABB(self.allDungeonSegments[j]:GetAABB(Entity.GlobalAABB)) then
    System:Print(dungeon[i]:GetKeyValue("name").." intersects with "..self.allDungeonSegments[j]:GetKeyValue("name"))
    if i<4 then
    return dungeon, false
    else
    System:Print("Three steps back")
    self:DeleteSegment(dungeon[i])
    System:Print("Deleted last segment")
    dungeon[i]=nil
    self:DeleteSegment(dungeon[i-1])
    System:Print("Deleted i-1")
    dungeon[i]=nil
    self:DeleteSegment(dungeon[i-2])
    System:Print("Deleted i-2")
    dungeon[i]=nil
    i=i-3
    j=1000--maximum+1
    end
    end
    end
    j=j+1
    end
    i=i+1
    --System:Print("End of I loop. i="..i)
    end
    return dungeon, true --returning true if managed to generate dungeon properly
    end
    function Script:GenerateForks()
    local i=1
    while i <= #self.dungeon do
    if self.dungeon[i]:GetKeyValue("name")=="BaseRoom" and math.random(0, 20)==0 then
    local matrix=self.dungeon[i]:GetMatrix(true)
    self:DeleteSegment(self.dungeon[i])
    self.dungeon[i]={}
    self.dungeon[i][0]=self:CreateSegment(self:GetRandomPart(4,5))
    self.dungeon[i][0]:SetMatrix(matrix, true)
    self.dungeon[i][1]=self:CreateSegment(self:GetRandomPart())
    local yRotation=self.dungeon[i][0]:GetRotation(true).y+self:GetExtraRotation(self.dungeon[i][0]) --second element
    self.dungeon[i][1]:SetRotation(0,yRotation,0,true)
    pos = self.dungeon[i][1]:FindChild("Enter"):GetPosition(true)
    previousPos = self.dungeon[i][0]:FindChild("Exit2"):GetPosition(true)
    dPos = pos-previousPos
    self.dungeon[i][1]:SetPosition(self.dungeon[i][1]:GetPosition(true)-dPos, true)
    --local dungeon
    --local result
    local dungeon, result = self:GeneratePath(15, self.dungeon[i], 30)
    if not result then
    self:DeleteSegment(dungeon[#dungeon])
    self.dungeon[i]=dungeon
    else
    self.dungeon[i]=dungeon
    end
    end
    i=i+1
    end
    end
    --other function
    function Script:GetRandomPart(minimum, maximum) --Choose random element
    if not minimum then minimum=0; maximum=3 end
    local r=math.random(minimum, maximum)
    if r==1 or r==0 then
    return self.BaseRoom
    elseif r==2 then
    return self.Hallway
    elseif r==3 then
    return self.Intersection
    elseif r==4 then
    return self.Corner
    elseif r==5 then
    return self.Stairs
    end
    end
    function Script:GetExtraRotation(name)
    name=name:GetKeyValue("name")
    if name=="Hallway" or name=="Intersection" then
    return (90)
    elseif name=="Hallway" or name=="Intersection" then
    return (-90)
    end
    return 0 --all other segments return 0
    end
    function Script:CreateSegment(name)
    local entity=Prefab:Load(name)
    table.insert (self.allDungeonSegments, entity)
    return entity
    end
    function Script:DeleteSegment(entity)
    local i=1
    local maximum=#self.allDungeonSegments
    while i<=maximum do
    if self.allDungeonSegments[i]==entity then
    local temp = self.allDungeonSegments[i]
    table.remove (self.allDungeonSegments, i)
    --self.allDungeonSegments[i]=0
    temp:Release()
    i=maximum
    end
    i=i+1
    end
    end
    function Script:DeleteAllDungeonSegments()
    for i=1, #self.allDungeonSegments do
    self.allDungeonSegments[i]:Release()
    end
    self.allDungeonSegments={}
    end
    function Script:IsDungeonSegment(name) --not needed
    name=name:GetKeyValue("name")
    for i=1, #self.names do
    if self.names[i]==name then return true end
    end
    return false
    end
    

    and now when i run it i get an error with startPivot as a nil value i odnt know why. Even if i set the pivot to a value like "Exit2" or "Exit" or even "Enter" it still gives me the nil value?

  4. I dont have and huge amounths of LUA scripting knowlege, but i understand the basics, i read all the LUA tutorials on the leadworks site. What im trying to do is create a single base room where the player starts, there is one exit, and after that exit using prefabs to randomly generate the rest of the map. Is this possible? Ive read forums on it(on this website, couldnt find one that helped, at the end of this post ill link some of the forums i read, i read all the ocmments as well), i just cant seem to figure it out and its killing me, ive been working on it for 16 hours straight. So if anyone is willing to help me out i would appreciate it. I dont even know how to start other than making prefabs with clear entrances and exits.

    a:http://www.leadwerks.com/werkspace/blog/52/entry-882-lets-make-a-game-procedual-content-creation-part-01/

    b:http://www.leadwerks.com/werkspace/topic/12430-procedural-generation/

    c:http://www.leadwerks.com/werkspace/topic/12063-procedural-generated-levels-using-prefabs/

    d:http://www.leadwerks.com/werkspace/topic/8168-procedural-generation-possible/

×
×
  • Create New...