Author Topic: Noah  (Read 7230 times)

Offline Erik

  • Lead Software Developer
  • Leadership Team
  • *
  • Posts: 1,310
  • SQL, C++, C#, UnrealScript, and SVN Admin
    • View Profile
    • About Me
Re: eggmunkee
« Reply #175 on: 14 July 2011, 23:49:14 »
I downloaded the code and applied it to the June UDK.  I encountered a good number of type coercion-related errors over the course of applying it.  I tried to use my best judgment to resolve them; however, I must be lacking the full context necessary to fix it properly because running the UDK crashes during the startup video.  Here is a list of the unique errors I encountered:

Code: [Select]
C:\UDK\UDK-2011-06\Development\Src\SRA\Classes\SraInventoryManager.uc(497) : Error, Type mismatch in Call to 'SetCurrentItem', parameter 1

C:\UDK\UDK-2011-06\Development\Src\SRA\Classes\SraInventoryData.uc(190) : Error, Type mismatch in 'Return'

C:\UDK\UDK-2011-06\Development\Src\SRA\Classes\SraPawn.uc(276) : Error, Type mismatch in Call to 'ServerSetTarget', parameter 1

C:\UDK\UDK-2011-06\Development\Src\SRA\Classes\CombatBase.uc(432) : Error, Type mismatch in Call to 'CheckTimers', parameter 1
C:\UDK\UDK-2011-06\Development\Src\SRA\Classes\CombatBase.uc(369) : Error, Type mismatch in '='

C:\UDK\UDK-2011-06\Development\Src\SRA\Classes\PhysicalCombat.uc(15) : Error, Type mismatch in Call to 'DrainStimulant', parameter 1

C:\UDK\UDK-2011-06\Development\Src\SRA\Classes\SraHumanoid.uc(448) : Error, Type mismatch in Call to 'CheckLOS', parameter 1

C:\UDK\UDK-2011-06\Development\Src\SRA\Classes\SraHumanoid.uc(577) : Error, Type mismatch in Call to 'SetCurrentItem', parameter 1

I'll keep tinkering on it best I can, but it's tough to catch up on context and what could crash.  Might have to try rolling back the code a bit, then incrementally adding things to see where it breaks.  More on Sunday.
« Last Edit: 15 July 2011, 01:26:47 by Erik »
About Me | Follow me on Twitter

Offline Noah

  • Scripter
  • Leadership Team
  • *
  • Posts: 479
    • View Profile
Re: eggmunkee
« Reply #176 on: 15 July 2011, 08:32:31 »
Just after glancing at some, I think they've changed the strictness of when an Interface is automatically converted to another class. Previously, if you passed an variable of an interface type to a function that had a class type parameter, it would automatically convert either to that class or to None. It seems they tightened that up. I don't think it will be too difficult to fix. Probably just adding an explicit cast to those places would fix that type of error. If I have time I'll scan through the rest and give you any other insights I have.

Oh, also I think I've seem some crashes with bad Interface use, I wish I could recall exactly what. :( I'm sure we'll figure it out.
-Noah, UDK Scripter/Rigger :)
SKYPE: Eggmunkee

Offline Noah

  • Scripter
  • Leadership Team
  • *
  • Posts: 479
    • View Profile
Re: eggmunkee
« Reply #177 on: 18 July 2011, 13:23:17 »
Small update on the Dialog functionality. I've added in the beginnings of a token system, where you can insert specific information into dialog from the current context it is run under. To explain "context" a bit further, whenever an event is setup or a Kislet tree is run, a dictionary is passed in that represents information about the context the logic is running under. Right now, the player's SraHumanoid actor is passed along under the name "Player". And SraPawn and SraHumanoid are now script-accessible objects through the IScriptable interface, with one read-only property implemented: UniqueID (string). This property returns the unique internal name for the player.

So I have the default dialog including a token to insert the player's id into the dialog shown. It looks like this:

Quote
Hey {Player.UniqueID}! You look new here. Can I help you with something?

This is the dialog text for the initial statement of the default dialog tree. When this dialog is being loaded for communication to the player, it parses any tokens in the text and replaces them with the value returned. So it looks in the context dictionary (aka Globals as it is sometimes called) for a key named "Player", getting some kind of property. If it's an ObjectScriptProperty (a scriptable actor), or a DictScriptProperty (a nested dictionary under Globals), it will take the next part of the token "UniqueID", and try to get that property. This process goes on until there aren't any more tokens. Right now a StringScriptProperty is the only valid ending point for a token, but eventually conversions from other types will be added (such as from IntScriptProperty to string).

Tokens will help dialog be more flexible, more re-usable and more specific to the player and the circumstances.

Below is a screenshot of the crappy UI temporarily being used right now.
« Last Edit: 18 July 2011, 13:36:51 by Noah »
-Noah, UDK Scripter/Rigger :)
SKYPE: Eggmunkee

Offline Noah

  • Scripter
  • Leadership Team
  • *
  • Posts: 479
    • View Profile
Re: eggmunkee
« Reply #178 on: 26 July 2011, 15:09:44 »
I'm now working under June Beta. I have done some work on Kislet, such as adding a SetBool op, a condition op to branch based on a bool variable, implementing "MaxTriggers" property of a DynamicEvent (so an event can fire off a given number of times before deleting itself), and adding a ScriptPropertyBase subclass NoneProperty.

NoneProperty is used to represent the value None that exists in Python. I haven't fully planned it's use, but I want it to work as similarly as possible to python. I just need to clear up when methods return UnrealScript's None and when they return the NoneProperty. One other issue I want to make sure I've dealt with is the fact that variables can continually change type. I think this will be handled by the fact that local and global variables are kept in DictScriptProperties with the key being the variable name. The value can just be overwritten by new values of whatever type. [Edit: Removed this fragment: "I may remove the". Not sure what I was in the middle of typing...]

Side note: Something amazing about UnrealScript is it lets me define a function within ScriptPropertyBase that returns an object of a derived class (NoneProperty). I did this so that any property type can call GetNone() and get a single global None property rather than continually creating them as needed (since they are all the same static value).

Yet another plan I have is to build a test class to do a number of unit tests in the ScriptVM and KisletManager so that we can identify current gaps in functionality and prevent future changes from introducing regressions.
« Last Edit: 30 July 2011, 01:49:16 by Noah »
-Noah, UDK Scripter/Rigger :)
SKYPE: Eggmunkee

Offline Noah

  • Scripter
  • Leadership Team
  • *
  • Posts: 479
    • View Profile
Re: eggmunkee
« Reply #179 on: 30 July 2011, 01:55:43 »
I've removed the PropertyName part of all ScriptPropertyBase types Create methods, because a Property is really a value not a variable. What makes it a variable is being referenced by a Dictionary of locals or something else. There was one case that seemed to need this which I am investigating how to remove. Some of the current test code for the ScriptVM may not work now, but nothing is really using it yet.

I have been studying the Python bytecode interpreter for some insight and to bring our script interpreter closer to being compatible with Python originated code. Helpful reference link for me: http://docs.python.org/library/dis.html#bytecodes

I'm delighted that no less than 5 threads in Development logs have been updated after mine, and mine was updated just 3 days ago. Things are buzzing here. :)
-Noah, UDK Scripter/Rigger :)
SKYPE: Eggmunkee

Offline Park

  • Shadowrunner
  • *
  • Posts: 61
    • View Profile
Re: eggmunkee
« Reply #180 on: 30 July 2011, 08:00:17 »
Does that dictionary also house other player information?   Such as racial choices or "apparent" cyberware?  So instead of "Hey Joe!"  We get the more generic "Hey Troll!" Or even "Hey Decker!"

Offline Noah

  • Scripter
  • Leadership Team
  • *
  • Posts: 479
    • View Profile
Re: eggmunkee
« Reply #181 on: 1 August 2011, 12:47:21 »
Yes, many things could be available to a dialog script. The Player object can access any of the Character attributes, race, gender, and anything else we would care to add. Included is the Essence rating (which could tell you how cyberware modified or unmodified a character is), or other additional appearance type fields we could create. It would probably look like "{Player.Character.Essense}" to reference the essence in the text of a dialog node.

Edit: I realized you probably wouldn't want to pipe the essence into a dialog. Instead you'd either call a script to generate an appropriate name beforehand and then pipe in that attached variable or context variable. Calling a script would be a node prior to the dialog node which has a variable attached to store the script's result in. Then the same variable would be connected to the Dialog node and it would have something like "{{0}}" or some other syntax in the dialog text to reference a connected variable. This part is not worked out yet.
« Last Edit: 1 August 2011, 15:00:40 by Noah »
-Noah, UDK Scripter/Rigger :)
SKYPE: Eggmunkee

Offline Park

  • Shadowrunner
  • *
  • Posts: 61
    • View Profile
Re: eggmunkee
« Reply #182 on: 1 August 2011, 15:53:03 »
Sorry Noah, I am not a programmer...yet.  Can we create a unique dictionary one a per NPC basis?  Is this how we'll track things like mission histor, or when the last time an NPC purchased paydata?  Or is this handled by some other library?  (Sorry my syntax may be wrong libraries and such.)

Offline Erik

  • Lead Software Developer
  • Leadership Team
  • *
  • Posts: 1,310
  • SQL, C++, C#, UnrealScript, and SVN Admin
    • View Profile
    • About Me
Re: eggmunkee
« Reply #183 on: 1 August 2011, 16:49:55 »
For each player on a mission, there will be one dictionary for during arbitrary string days in the database, there will be similar arbitrary data dictionaries for each players contacts, enemies, and story. How that integrated with scripting is up in the air, but each should be object-oriented and always tied back to a particular player character instance, so it will be simple to understand.

About Me | Follow me on Twitter

Offline Park

  • Shadowrunner
  • *
  • Posts: 61
    • View Profile
Re: eggmunkee
« Reply #184 on: 1 August 2011, 18:20:09 »
I guess I am interested in persistancy of data across multiple players.  For instance, if I have Mr. Johnson (Horst Mayweather) and my friend does to, can the NPC's make "recommendations" on additional players to join you based on karma, reputation, and other factors such as affiliations.  I am sure there are other uses for that data as well (2.0) but wasn't sure if it could be neatly added on later.

Offline Noah

  • Scripter
  • Leadership Team
  • *
  • Posts: 479
    • View Profile
Re: eggmunkee
« Reply #185 on: 2 August 2011, 00:22:30 »
I think data like ratings and stats would be generally available to most aspects of the game, just a matter of choosing to use them IMO. I'm not sure specifically how the Fixer conversation and things will be setup, I think this is techincally possible to do though.
-Noah, UDK Scripter/Rigger :)
SKYPE: Eggmunkee

Offline Noah

  • Scripter
  • Leadership Team
  • *
  • Posts: 479
    • View Profile
Re: eggmunkee
« Reply #186 on: 3 August 2011, 00:03:18 »
I started applying some macros to simplify code in the ScriptVM package. Instead of
Code: [Select]
StringProp = class'StringScriptProperty'.static.Create("a string", ParentProp);with the macro this becomes
Code: [Select]
StringProp = `NewString("a string", ParentProp);
Also I added a global macro file "Globals.uci" which sits just above the Classes directory in a package. I added one in ScriptVM which defines what is above, and I added one in SRA which simply includes the ScriptVM ones, plus we can add whatever more we want here later.

I did some work on a unit testing class, but not much.
-Noah, UDK Scripter/Rigger :)
SKYPE: Eggmunkee

Offline Erik

  • Lead Software Developer
  • Leadership Team
  • *
  • Posts: 1,310
  • SQL, C++, C#, UnrealScript, and SVN Admin
    • View Profile
    • About Me
Re: eggmunkee
« Reply #187 on: 3 August 2011, 00:32:51 »
Good job!  Way to leverage the platform to make life easy for the humans :)
About Me | Follow me on Twitter

Offline Noah

  • Scripter
  • Leadership Team
  • *
  • Posts: 479
    • View Profile
Re: eggmunkee
« Reply #188 on: 4 August 2011, 18:10:18 »
Now we have named parameters, parameter defaults, and other Python-y tweaks. I've added more macros for script property manipulation, such as:

New<TypeHere>(value, parent, vm) - For all major types
IsNone(value), IsTrue(value) - giving python's unique truth values
Comparison tests each with (a,b) params: Equals, NotEquals, GreaterThan, LessThan, GreaterEquals, LessEquals
Binary operations with (a,b) params: Add, Sub, Mult, Div
Sequence operations for dicts and lists: SetItem(obj, key,value), GetItem(obj, key)
Sequence operations for lists only: Append(obj, value)

I'm sure I'll add more as needed. Helpful hint if you find syntax problems: use the -intermediate flag on building. It outputs the source files after preprocessors and macros have been applied.

I've also added I think 64 unit tests regarding ints, float, none's, and truthicity of various types. I'll try to keep adding here, such as function results and other things. That way I'll know when my changes break something previously working. :)
-Noah, UDK Scripter/Rigger :)
SKYPE: Eggmunkee

Offline Noah

  • Scripter
  • Leadership Team
  • *
  • Posts: 479
    • View Profile
Re: eggmunkee
« Reply #189 on: 5 August 2011, 18:19:50 »
Improved support for function parameters being None and the default values working. Added macros for defining setters and getters for scriptable classes. Added unit tests for function calling. Improved python object string representation.

Here's how you can define setters and getters for a scriptable class (first it must implement the interface IScriptable).

Setter that calls a function:
Code: [Select]
`BeginSetter
`CallFuncValue(ViewSetting, StringScriptProperty, SetViewByName)
`EndSetter
Which turns into this code:
Code: [Select]
function Set(string propertyName, ScriptPropertyBase Prop) {
if (propertyName ~= "ViewSetting" && ((StringScriptProperty (Prop )) != None)) {
SetViewByName ( ( StringScriptProperty (Prop)).PropValue );
}
}
So when you do "controller.ViewSetting = 'ZoomedOut'" it will call the SetViewByName('ZoomedOut') in the controller.

Getters can get their value from various places.
Code: [Select]
`BeginGetter
`ReturnVarValue(ViewSetting, StringScriptProperty, GetViewSettingName())
`ReturnVarValue(Location, VectorScriptProperty, Location)
`ReturnVarValue(Health, IntScriptProperty, SraPawn(Pawn).GetHealth(DAMAGE_Physical) )
`EndGetter
Which turns into this code:
Code: [Select]
function ScriptPropertyBase Get(string propertyName) {
if (propertyName ~= "ViewSetting") {
return class'StringScriptProperty'.static.Create(GetViewSettingName());
}
if (propertyName ~= "Location") {
return class'VectorScriptProperty'.static.Create(Location);
}
if (propertyName ~= "Health") {
return class'IntScriptProperty'.static.Create(SraPawn(Pawn).GetHealth(DAMAGE_Physical));
}
}
With the getter whatever you put in the third parameter will be what value is set and returned to the script.

This just makes it easier to add or change what variables are exposed and also change the implementation in one place (in stead of changing things everyplace there is a getter/setter code block).
-Noah, UDK Scripter/Rigger :)
SKYPE: Eggmunkee

Offline Sean

  • Lead Sound Designer
  • Leadership Team
  • *
  • Posts: 538
  • Audio Lead
    • View Profile
    • VI Productions
Re: eggmunkee
« Reply #190 on: 5 August 2011, 18:55:12 »
sigh.. I wish I understood half of what you wrote after the word macros. 
Sean S
Lead Sound Designer / Audio Engineer
sean (AT) VIProductions (DOT) net
SKYPE: viptampa

Offline Noah

  • Scripter
  • Leadership Team
  • *
  • Posts: 479
    • View Profile
Re: eggmunkee
« Reply #191 on: 6 August 2011, 00:58:40 »
Getters and setters are basically functions to access variables. Say if we want a script to be able to get a player's health, it is calling a function that returns the health to it. That is basically what a getter does. Setters just set a object's value for a particular variable. Same example works, if we wanted to allow a script to update a player's health it would call the setter function. They are part of the interface through which scripts can interact with the various objects in the game. Hope that helped!
« Last Edit: 6 August 2011, 01:03:13 by Noah »
-Noah, UDK Scripter/Rigger :)
SKYPE: Eggmunkee

Offline Sean

  • Lead Sound Designer
  • Leadership Team
  • *
  • Posts: 538
  • Audio Lead
    • View Profile
    • VI Productions
Re: eggmunkee
« Reply #192 on: 6 August 2011, 02:25:07 »
:)  you're very kind.  Ty
Sean S
Lead Sound Designer / Audio Engineer
sean (AT) VIProductions (DOT) net
SKYPE: viptampa

Offline Noah

  • Scripter
  • Leadership Team
  • *
  • Posts: 479
    • View Profile
Re: eggmunkee
« Reply #193 on: 9 August 2011, 18:34:39 »
I've just done some preliminary testing on the ast module in python. This is an abstract syntax tree module that can parse python into a syntax tree. With the help of the ast.NodeVisitor (which you subclass) we should be able to take python code and output the text that our ScriptVM interpreter reads in. Basically it consists of defining how to write out all the types of expressions. Here's the current python class I have written:

Code: [Select]
import ast
import types

class MyVis(ast.NodeVisitor):
def __init__(self):
self.ind = 0
def getTab(self, off=0):
return (self.ind + off) * ' '
def generic_visit(self, node):
print self.getTab() + str(type(node))
print self.getTab(2) + str(node._fields)
self.ind += 4
ast.NodeVisitor.generic_visit(self, node)
self.ind -= 4
def visit_Name(self, node):
#print self.getTab() + 'Name: ' + node.id
name = type(node.ctx).__name__
if name == 'Store':
print self.getTab() + 'SETLOC,' + node.id
elif name == 'Load':
print self.getTab() + 'GETLOC,' + node.id
elif name == 'Param':
print self.getTab() + 'PARAM?,' + node.id
def visit_Num(self, node):
if (type(node.n) == types.IntType):
print self.getTab() + 'PUSHI,' + str(node.n)
elif (type(node.n) == types.FloatType):
print self.getTab() + 'PUSHF,' + str(node.n)
def visit_Assign(self, node):
print self.getTab() + 'Assign:'
self.ind += 4
print self.getTab(-4) + 'Assign Value: '
ast.NodeVisitor.visit(self,node.value)
for n in node.targets:
ast.NodeVisitor.visit(self,n)
self.ind -= 4
def visit_BinOp(self, node):
ast.NodeVisitor.visit(self,node.left)
ast.NodeVisitor.visit(self,node.left)
print self.getTab() + 'CMP,' + type(node.op).__name__
This is already starting to generate the bytecodes and their arguments for some things like retrieving variables, etc. I see this as very feasible for our timeframe and this is really exciting, because I was not wanting to have to try to write some kind of parser from scratch!  ;D
-Noah, UDK Scripter/Rigger :)
SKYPE: Eggmunkee

Offline Noah

  • Scripter
  • Leadership Team
  • *
  • Posts: 479
    • View Profile
Re: eggmunkee
« Reply #194 on: 13 August 2011, 03:18:04 »
Things are really coming together. I am now able to write a great deal of python code that will import directly into ScriptVM and run without tweaking. By running a python script you can translate a python file to a block of opcodes and parameters which you can run from the UDK console. I'm just pasting from one to the other right now.

This process could be implemented a few ways eventually. The python program could be shelled out from the mission-scripting interface and the pre-translated code is saved in the database, and that code is loaded into UDK to run. We could also have a dll which UDK could call on, which in turn would call on python to translate python text to scriptvm interpereter code real-time as well if needed. The latter seems like it would mainly be necessary if we wanted more in-game editing and debugging abilities. I think I will be wrapping up the ScriptVM for the most part in the next week at the most, so I can shift to working on Dialog and Missions/Objectives again and keep to my goals for August.

Here's a taste of the before and after.

Python file to return a status based on player's physical and stun health:
Code: [Select]
global character

h = character.gethealth()

if character.hashealth('stun'):
s = character.gethealth('stun')
else:
s = 0

if 0 < s < h:
return 'Feeling pumped up'
elif 0 < s:
return 'Feeling sharp minded'
else:
return 'Feeling bad!'

Here's the output in interpreter code:
Code: [Select]
GETGLB,character
GETATTR,gethealth
CALL,0
SETLOC,h
IF
GETGLB,character
GETATTR,hashealth
PUSHS,stun
CALL,1
TEST
GETGLB,character
GETATTR,gethealth
PUSHS,stun
CALL,1
SETLOC,s
ELSE
PUSHI,0
SETLOC,s
END
IF
PUSHI,0
GETLOC,s
DUP
ROT_3
CMP,<
JMPF_OR_POP,4
GETLOC,h
CMP,<
JMP_REL,3
ROT_2
POP
TEST
PUSHS,Feeling\_pumped\_up
RETURN
ELSE
IF
PUSHI,0
GETLOC,s
CMP,<
TEST
PUSHS,Feeling\_sharp\_minded
RETURN
ELSE
PUSHS,Feeling\_bad!
RETURN
END
END

Yeah, it's a little like looking at assembly code mixed with basic. That's a virtual machine for ya.
-Noah, UDK Scripter/Rigger :)
SKYPE: Eggmunkee

Offline Noah

  • Scripter
  • Leadership Team
  • *
  • Posts: 479
    • View Profile
Re: eggmunkee
« Reply #195 on: 18 August 2011, 17:51:08 »
Python support has come along enough and I've added enough useful methods that I have written our first "mission script". Running it in-game adds a new mission with a sub-tree of objectives. It looks at the global "currentTarget" and if set it makes the objective to talk to that player 5 times. Otherwise the objective is to talk to anyone 5 times. It takes about 1ms to run this script. Here is the python code for the script:

Code: [Select]
global game, currenttarget

m = game.addmission()

obj = object('Sra.MissionObjective', game)
obj.tag = 'SuperMission'
m.objectivetree = obj

objCount = object('Sra.Obj_Counter', game)
objCount.Tag = 'DoThis5Times'
objCount.CountTarget = 5
obj.subobjectives = [objCount]

objTalk = object('Sra.Obj_TalkTo', game)
objTalk.tag = 'TalkToTarget'
if currenttarget:
print currenttarget, currenttarget.uniqueID
objTalk.npcId = currenttarget.uniqueID
objCount.subObjectives = [objTalk]

Those object() method calls are what create real objects or actors in the engine, taking a string name of the class and a parent object of the new object. Setting subobjectives of an objective sends a list over to the missionobjective class which replaces the current subobjectives. The Tag objective variable is just kind of a note on the object for us humans. Let me know if anyone has questions about how this will work.
-Noah, UDK Scripter/Rigger :)
SKYPE: Eggmunkee

Offline Curtis888

  • Mission Dialogue Manager
  • Assets Team
  • *
  • Posts: 383
  • "Love is love & nothing else." -Curtis Lee Cancino
    • View Profile
Re: eggmunkee
« Reply #196 on: 19 August 2011, 15:54:20 »
I'm not sure if I completely understand what you said, but I know that is damned good news for the project. :D
Assests Think-tank
Skype name: kingsmen96
curtiscancino8@aol.com
"The Dragon is nothing like as powerful as they want us to believe it is." -David Icke

Offline Noah

  • Scripter
  • Leadership Team
  • *
  • Posts: 479
    • View Profile
Re: Noah
« Reply #197 on: 28 August 2011, 23:33:50 »
I posted this in the UnrealScript August Milestone thread:
Quote
Updated last tasks for August to DONE! :) The arena brawl rules are now implemented at the basic level they were with our new mission objective classes, created by a hard-coded python script. So now you can play combat football with shadowrun rules if ya want to. Who wouldn't?

Now, it's on to September tasks!

FYI there's a targeting bug when playing client-server, and that's not a big deal for the demo, but I might try to squeeze in that fix in case someone wants to play Arena Brawl sometime. :)
-Noah, UDK Scripter/Rigger :)
SKYPE: Eggmunkee

Offline Sean

  • Lead Sound Designer
  • Leadership Team
  • *
  • Posts: 538
  • Audio Lead
    • View Profile
    • VI Productions
Re: Noah
« Reply #198 on: 29 August 2011, 07:39:29 »
Me!

I'd love to squeeze in some arena brawl if you get time. (already considering renting a server in December just in case we get enough code done for that)
Sean S
Lead Sound Designer / Audio Engineer
sean (AT) VIProductions (DOT) net
SKYPE: viptampa

Offline Noah

  • Scripter
  • Leadership Team
  • *
  • Posts: 479
    • View Profile
Re: Noah
« Reply #199 on: 29 August 2011, 18:17:05 »
I did some work on basic AI we'll need for December (see UnrealScript September milestone thread). These are some screenshots of npcs following the player and sneaking when he sneaks.
-Noah, UDK Scripter/Rigger :)
SKYPE: Eggmunkee


Social Bookmarks

Smf

 

anything